Home | History | Annotate | Line # | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      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.
      7  *
      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.
     12  *
     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]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 /*
     27  * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
     28  */
     29 
     30 #include <assert.h>
     31 #include <strings.h>
     32 #include <stdlib.h>
     33 #include <stdio.h>
     34 #include <errno.h>
     35 #include <ctype.h>
     36 #ifdef illumos
     37 #include <alloca.h>
     38 #endif
     39 #include <libgen.h>
     40 #include <stddef.h>
     41 #include <sys/sysmacros.h>
     42 
     43 #include <dt_impl.h>
     44 #include <dt_program.h>
     45 #include <dt_pid.h>
     46 #include <dt_string.h>
     47 #include <dt_module.h>
     48 
     49 #ifndef illumos
     50 #include <sys/sysctl.h>
     51 #include <sys/ioctl.h>
     52 #include <unistd.h>
     53 #include <libproc_compat.h>
     54 #include <libelf.h>
     55 #include <gelf.h>
     56 #endif
     57 
     58 typedef struct dt_pid_probe {
     59 	dtrace_hdl_t *dpp_dtp;
     60 	dt_pcb_t *dpp_pcb;
     61 	dt_proc_t *dpp_dpr;
     62 	struct ps_prochandle *dpp_pr;
     63 	const char *dpp_mod;
     64 	char *dpp_func;
     65 	const char *dpp_name;
     66 	const char *dpp_obj;
     67 	uintptr_t dpp_pc;
     68 	size_t dpp_size;
     69 	Lmid_t dpp_lmid;
     70 	uint_t dpp_nmatches;
     71 	uint64_t dpp_stret[4];
     72 	GElf_Sym dpp_last;
     73 	uint_t dpp_last_taken;
     74 } dt_pid_probe_t;
     75 
     76 /*
     77  * Compose the lmid and object name into the canonical representation. We
     78  * omit the lmid for the default link map for convenience.
     79  */
     80 static void
     81 dt_pid_objname(char *buf, size_t len, Lmid_t lmid, const char *obj)
     82 {
     83 #ifdef illumos
     84 	if (lmid == LM_ID_BASE)
     85 		(void) strncpy(buf, obj, len);
     86 	else
     87 		(void) snprintf(buf, len, "LM%lx`%s", lmid, obj);
     88 #else
     89 	(void) strncpy(buf, obj, len);
     90 #endif
     91 }
     92 
     93 static int
     94 dt_pid_error(dtrace_hdl_t *dtp, dt_pcb_t *pcb, dt_proc_t *dpr,
     95     fasttrap_probe_spec_t *ftp, dt_errtag_t tag, const char *fmt, ...)
     96 {
     97 	va_list ap;
     98 	int len;
     99 
    100 	if (ftp != NULL)
    101 		dt_free(dtp, ftp);
    102 
    103 	va_start(ap, fmt);
    104 	if (pcb == NULL) {
    105 		assert(dpr != NULL);
    106 		len = vsnprintf(dpr->dpr_errmsg, sizeof (dpr->dpr_errmsg),
    107 		    fmt, ap);
    108 		assert(len >= 2);
    109 		if (dpr->dpr_errmsg[len - 2] == '\n')
    110 			dpr->dpr_errmsg[len - 2] = '\0';
    111 	} else {
    112 		dt_set_errmsg(dtp, dt_errtag(tag), pcb->pcb_region,
    113 		    pcb->pcb_filetag, pcb->pcb_fileptr ? yylineno : 0, fmt, ap);
    114 	}
    115 	va_end(ap);
    116 
    117 	return (1);
    118 }
    119 
    120 static int
    121 dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func)
    122 {
    123 	dtrace_hdl_t *dtp = pp->dpp_dtp;
    124 	dt_pcb_t *pcb = pp->dpp_pcb;
    125 	dt_proc_t *dpr = pp->dpp_dpr;
    126 	fasttrap_probe_spec_t *ftp;
    127 	uint64_t off;
    128 	char *end;
    129 	uint_t nmatches = 0;
    130 	ulong_t sz;
    131 	int glob, err;
    132 	int isdash = strcmp("-", func) == 0;
    133 	pid_t pid;
    134 
    135 #ifdef illumos
    136 	pid = Pstatus(pp->dpp_pr)->pr_pid;
    137 #else
    138 	pid = proc_getpid(pp->dpp_pr);
    139 #endif
    140 
    141 	dt_dprintf("creating probe pid%d:%s:%s:%s\n", (int)pid, pp->dpp_obj,
    142 	    func, pp->dpp_name);
    143 
    144 	sz = sizeof (fasttrap_probe_spec_t) + (isdash ? 4 :
    145 	    (symp->st_size - 1) * sizeof (ftp->ftps_offs[0]));
    146 
    147 	if ((ftp = dt_alloc(dtp, sz)) == NULL) {
    148 		dt_dprintf("proc_per_sym: dt_alloc(%lu) failed\n", sz);
    149 		return (1); /* errno is set for us */
    150 	}
    151 
    152 	ftp->ftps_pid = pid;
    153 	(void) strncpy(ftp->ftps_func, func, sizeof (ftp->ftps_func));
    154 
    155 	dt_pid_objname(ftp->ftps_mod, sizeof (ftp->ftps_mod), pp->dpp_lmid,
    156 	    pp->dpp_obj);
    157 
    158 	if (!isdash && gmatch("return", pp->dpp_name)) {
    159 		if (dt_pid_create_return_probe(pp->dpp_pr, dtp, ftp, symp,
    160 		    pp->dpp_stret) < 0) {
    161 			return (dt_pid_error(dtp, pcb, dpr, ftp,
    162 			    D_PROC_CREATEFAIL, "failed to create return probe "
    163 			    "for '%s': %s", func,
    164 			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
    165 		}
    166 
    167 		nmatches++;
    168 	}
    169 
    170 	if (!isdash && gmatch("entry", pp->dpp_name)) {
    171 		if (dt_pid_create_entry_probe(pp->dpp_pr, dtp, ftp, symp) < 0) {
    172 			return (dt_pid_error(dtp, pcb, dpr, ftp,
    173 			    D_PROC_CREATEFAIL, "failed to create entry probe "
    174 			    "for '%s': %s", func,
    175 			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
    176 		}
    177 
    178 		nmatches++;
    179 	}
    180 
    181 	glob = strisglob(pp->dpp_name);
    182 	if (!glob && nmatches == 0) {
    183 		off = strtoull(pp->dpp_name, &end, 16);
    184 		if (*end != '\0') {
    185 			return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_NAME,
    186 			    "'%s' is an invalid probe name", pp->dpp_name));
    187 		}
    188 
    189 		if (off >= symp->st_size) {
    190 			return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_OFF,
    191 			    "offset 0x%llx outside of function '%s'",
    192 			    (u_longlong_t)off, func));
    193 		}
    194 
    195 		err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp,
    196 		    symp, off);
    197 
    198 		if (err == DT_PROC_ERR) {
    199 			return (dt_pid_error(dtp, pcb, dpr, ftp,
    200 			    D_PROC_CREATEFAIL, "failed to create probe at "
    201 			    "'%s+0x%llx': %s", func, (u_longlong_t)off,
    202 			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
    203 		}
    204 
    205 		if (err == DT_PROC_ALIGN) {
    206 			return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_ALIGN,
    207 			    "offset 0x%llx is not aligned on an instruction",
    208 			    (u_longlong_t)off));
    209 		}
    210 
    211 		nmatches++;
    212 
    213 	} else if (glob && !isdash) {
    214 		if (dt_pid_create_glob_offset_probes(pp->dpp_pr,
    215 		    pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) {
    216 			return (dt_pid_error(dtp, pcb, dpr, ftp,
    217 			    D_PROC_CREATEFAIL,
    218 			    "failed to create offset probes in '%s': %s", func,
    219 			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
    220 		}
    221 
    222 		nmatches++;
    223 	}
    224 
    225 	pp->dpp_nmatches += nmatches;
    226 
    227 	dt_free(dtp, ftp);
    228 
    229 	return (0);
    230 }
    231 
    232 static int
    233 dt_pid_sym_filt(void *arg, const GElf_Sym *symp, const char *func)
    234 {
    235 	dt_pid_probe_t *pp = arg;
    236 
    237 	if (symp->st_shndx == SHN_UNDEF)
    238 		return (0);
    239 
    240 	if (symp->st_size == 0) {
    241 		dt_dprintf("st_size of %s is zero\n", func);
    242 		return (0);
    243 	}
    244 
    245 	if (pp->dpp_last_taken == 0 ||
    246 	    symp->st_value != pp->dpp_last.st_value ||
    247 	    symp->st_size != pp->dpp_last.st_size) {
    248 		/*
    249 		 * Due to 4524008, _init and _fini may have a bloated st_size.
    250 		 * While this bug has been fixed for a while, old binaries
    251 		 * may exist that still exhibit this problem. As a result, we
    252 		 * don't match _init and _fini though we allow users to
    253 		 * specify them explicitly.
    254 		 */
    255 		if (strcmp(func, "_init") == 0 || strcmp(func, "_fini") == 0)
    256 			return (0);
    257 
    258 		if ((pp->dpp_last_taken = gmatch(func, pp->dpp_func)) != 0) {
    259 			pp->dpp_last = *symp;
    260 			return (dt_pid_per_sym(pp, symp, func));
    261 		}
    262 	}
    263 
    264 	return (0);
    265 }
    266 
    267 static int
    268 dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj)
    269 {
    270 	dt_pid_probe_t *pp = arg;
    271 	dtrace_hdl_t *dtp = pp->dpp_dtp;
    272 	dt_pcb_t *pcb = pp->dpp_pcb;
    273 	dt_proc_t *dpr = pp->dpp_dpr;
    274 	GElf_Sym sym;
    275 
    276 	if (obj == NULL)
    277 		return (0);
    278 
    279 #ifdef illumos
    280 	(void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
    281 #endif
    282 
    283 
    284 	if ((pp->dpp_obj = strrchr(obj, '/')) == NULL)
    285 		pp->dpp_obj = obj;
    286 	else
    287 		pp->dpp_obj++;
    288 #ifdef illumos
    289 	if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym,
    290 	    NULL) == 0)
    291 		pp->dpp_stret[0] = sym.st_value;
    292 	else
    293 		pp->dpp_stret[0] = 0;
    294 
    295 	if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret2", &sym,
    296 	    NULL) == 0)
    297 		pp->dpp_stret[1] = sym.st_value;
    298 	else
    299 		pp->dpp_stret[1] = 0;
    300 
    301 	if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret4", &sym,
    302 	    NULL) == 0)
    303 		pp->dpp_stret[2] = sym.st_value;
    304 	else
    305 		pp->dpp_stret[2] = 0;
    306 
    307 	if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret8", &sym,
    308 	    NULL) == 0)
    309 		pp->dpp_stret[3] = sym.st_value;
    310 	else
    311 		pp->dpp_stret[3] = 0;
    312 #else
    313 	pp->dpp_stret[0] = 0;
    314 	pp->dpp_stret[1] = 0;
    315 	pp->dpp_stret[2] = 0;
    316 	pp->dpp_stret[3] = 0;
    317 #endif
    318 
    319 	dt_dprintf("%s stret %llx %llx %llx %llx\n", obj,
    320 	    (u_longlong_t)pp->dpp_stret[0], (u_longlong_t)pp->dpp_stret[1],
    321 	    (u_longlong_t)pp->dpp_stret[2], (u_longlong_t)pp->dpp_stret[3]);
    322 
    323 	/*
    324 	 * If pp->dpp_func contains any globbing meta-characters, we need
    325 	 * to iterate over the symbol table and compare each function name
    326 	 * against the pattern.
    327 	 */
    328 	if (!strisglob(pp->dpp_func)) {
    329 		/*
    330 		 * If we fail to lookup the symbol, try interpreting the
    331 		 * function as the special "-" function that indicates that the
    332 		 * probe name should be interpreted as a absolute virtual
    333 		 * address. If that fails and we were matching a specific
    334 		 * function in a specific module, report the error, otherwise
    335 		 * just fail silently in the hopes that some other object will
    336 		 * contain the desired symbol.
    337 		 */
    338 		if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj,
    339 		    pp->dpp_func, &sym, NULL) != 0) {
    340 			if (strcmp("-", pp->dpp_func) == 0) {
    341 				sym.st_name = 0;
    342 				sym.st_info =
    343 				    GELF_ST_INFO(STB_LOCAL, STT_FUNC);
    344 				sym.st_other = 0;
    345 				sym.st_value = 0;
    346 #ifdef illumos
    347 				sym.st_size = Pstatus(pp->dpp_pr)->pr_dmodel ==
    348 				    PR_MODEL_ILP32 ? -1U : -1ULL;
    349 #else
    350 				sym.st_size = ~((Elf64_Xword) 0);
    351 #endif
    352 
    353 			} else if (!strisglob(pp->dpp_mod)) {
    354 				return (dt_pid_error(dtp, pcb, dpr, NULL,
    355 				    D_PROC_FUNC,
    356 				    "failed to lookup '%s' in module '%s'",
    357 				    pp->dpp_func, pp->dpp_mod));
    358 			} else {
    359 				return (0);
    360 			}
    361 		}
    362 
    363 		/*
    364 		 * Only match defined functions of non-zero size.
    365 		 */
    366 		if (GELF_ST_TYPE(sym.st_info) != STT_FUNC ||
    367 		    sym.st_shndx == SHN_UNDEF || sym.st_size == 0)
    368 			return (0);
    369 
    370 		/*
    371 		 * We don't instrument PLTs -- they're dynamically rewritten,
    372 		 * and, so, inherently dicey to instrument.
    373 		 */
    374 #ifdef DOODAD
    375 		if (Ppltdest(pp->dpp_pr, sym.st_value) != NULL)
    376 			return (0);
    377 #endif
    378 
    379 		(void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func,
    380 		    DTRACE_FUNCNAMELEN, &sym);
    381 
    382 		return (dt_pid_per_sym(pp, &sym, pp->dpp_func));
    383 	} else {
    384 		uint_t nmatches = pp->dpp_nmatches;
    385 
    386 		if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB,
    387 		    BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1)
    388 			return (1);
    389 
    390 		if (nmatches == pp->dpp_nmatches) {
    391 			/*
    392 			 * If we didn't match anything in the PR_SYMTAB, try
    393 			 * the PR_DYNSYM.
    394 			 */
    395 			if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_DYNSYM,
    396 			    BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1)
    397 				return (1);
    398 		}
    399 	}
    400 
    401 	return (0);
    402 }
    403 
    404 static int
    405 dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj)
    406 {
    407 	char name[DTRACE_MODNAMELEN];
    408 	dt_pid_probe_t *pp = arg;
    409 
    410 	if (gmatch(obj, pp->dpp_mod))
    411 		return (dt_pid_per_mod(pp, pmp, obj));
    412 
    413 #ifdef illumos
    414 	(void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
    415 #else
    416 	pp->dpp_lmid = 0;
    417 #endif
    418 
    419 	if ((pp->dpp_obj = strrchr(obj, '/')) == NULL)
    420 		pp->dpp_obj = obj;
    421 	else
    422 		pp->dpp_obj++;
    423 
    424 	if (gmatch(pp->dpp_obj, pp->dpp_mod))
    425 		return (dt_pid_per_mod(pp, pmp, obj));
    426 
    427 #ifdef illumos
    428 	(void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
    429 #endif
    430 
    431 	dt_pid_objname(name, sizeof (name), pp->dpp_lmid, pp->dpp_obj);
    432 
    433 	if (gmatch(name, pp->dpp_mod))
    434 		return (dt_pid_per_mod(pp, pmp, obj));
    435 
    436 	return (0);
    437 }
    438 
    439 static const prmap_t *
    440 dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P)
    441 {
    442 	char m[MAXPATHLEN];
    443 	Lmid_t lmid = PR_LMID_EVERY;
    444 	const char *obj;
    445 	const prmap_t *pmp;
    446 
    447 	/*
    448 	 * Pick apart the link map from the library name.
    449 	 */
    450 	if (strchr(pdp->dtpd_mod, '`') != NULL) {
    451 		char *end;
    452 
    453 		if (strncmp(pdp->dtpd_mod, "LM", 2) != 0 ||
    454 		    !isdigit((unsigned char)pdp->dtpd_mod[2]))
    455 			return (NULL);
    456 
    457 		lmid = strtoul(&pdp->dtpd_mod[2], &end, 16);
    458 
    459 		obj = end + 1;
    460 
    461 		if (*end != '`' || strchr(obj, '`') != NULL)
    462 			return (NULL);
    463 
    464 	} else {
    465 		obj = pdp->dtpd_mod;
    466 	}
    467 
    468 	if ((pmp = Plmid_to_map(P, lmid, obj)) == NULL)
    469 		return (NULL);
    470 
    471 	(void) Pobjname(P, pmp->pr_vaddr, m, sizeof (m));
    472 	if ((obj = strrchr(m, '/')) == NULL)
    473 		obj = &m[0];
    474 	else
    475 		obj++;
    476 
    477 #ifdef illumos
    478 	(void) Plmid(P, pmp->pr_vaddr, &lmid);
    479 #endif
    480 
    481 	dt_pid_objname(pdp->dtpd_mod, sizeof (pdp->dtpd_mod), lmid, obj);
    482 
    483 	return (pmp);
    484 }
    485 
    486 
    487 static int
    488 dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
    489     dt_pcb_t *pcb, dt_proc_t *dpr)
    490 {
    491 	dt_pid_probe_t pp;
    492 	int ret = 0;
    493 
    494 	pp.dpp_dtp = dtp;
    495 	pp.dpp_dpr = dpr;
    496 	pp.dpp_pr = dpr->dpr_proc;
    497 	pp.dpp_pcb = pcb;
    498 
    499 #ifdef DOODAD
    500 	/*
    501 	 * We can only trace dynamically-linked executables (since we've
    502 	 * hidden some magic in ld.so.1 as well as libc.so.1).
    503 	 */
    504 	if (Pname_to_map(pp.dpp_pr, PR_OBJ_LDSO) == NULL) {
    505 		return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_DYN,
    506 		    "process %s is not a dynamically-linked executable",
    507 		    &pdp->dtpd_provider[3]));
    508 	}
    509 #endif
    510 
    511 	pp.dpp_mod = pdp->dtpd_mod[0] != '\0' ? pdp->dtpd_mod : "*";
    512 	pp.dpp_func = pdp->dtpd_func[0] != '\0' ? pdp->dtpd_func : "*";
    513 	pp.dpp_name = pdp->dtpd_name[0] != '\0' ? pdp->dtpd_name : "*";
    514 	pp.dpp_last_taken = 0;
    515 
    516 	if (strcmp(pp.dpp_func, "-") == 0) {
    517 		const prmap_t *aout, *pmp;
    518 
    519 		if (pdp->dtpd_mod[0] == '\0') {
    520 			pp.dpp_mod = pdp->dtpd_mod;
    521 			(void) strcpy(pdp->dtpd_mod, "a.out");
    522 		} else if (strisglob(pp.dpp_mod) ||
    523 		    (aout = Pname_to_map(pp.dpp_pr, "a.out")) == NULL ||
    524 		    (pmp = Pname_to_map(pp.dpp_pr, pp.dpp_mod)) == NULL ||
    525 		    aout->pr_vaddr != pmp->pr_vaddr) {
    526 			return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_LIB,
    527 			    "only the a.out module is valid with the "
    528 			    "'-' function"));
    529 		}
    530 
    531 		if (strisglob(pp.dpp_name)) {
    532 			return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_NAME,
    533 			    "only individual addresses may be specified "
    534 			    "with the '-' function"));
    535 		}
    536 	}
    537 
    538 	/*
    539 	 * If pp.dpp_mod contains any globbing meta-characters, we need
    540 	 * to iterate over each module and compare its name against the
    541 	 * pattern. An empty module name is treated as '*'.
    542 	 */
    543 	if (strisglob(pp.dpp_mod)) {
    544 		ret = Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp);
    545 	} else {
    546 		const prmap_t *pmp;
    547 		char *obj;
    548 
    549 		/*
    550 		 * If we can't find a matching module, don't sweat it -- either
    551 		 * we'll fail the enabling because the probes don't exist or
    552 		 * we'll wait for that module to come along.
    553 		 */
    554 		if ((pmp = dt_pid_fix_mod(pdp, pp.dpp_pr)) != NULL) {
    555 			if ((obj = strchr(pdp->dtpd_mod, '`')) == NULL)
    556 				obj = pdp->dtpd_mod;
    557 			else
    558 				obj++;
    559 
    560 			ret = dt_pid_per_mod(&pp, pmp, obj);
    561 		}
    562 	}
    563 
    564 	return (ret);
    565 }
    566 
    567 static int
    568 dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
    569 {
    570 	struct ps_prochandle *P = data;
    571 	GElf_Sym sym;
    572 	prsyminfo_t sip;
    573 	dof_helper_t dh;
    574 	GElf_Half e_type;
    575 	const char *mname;
    576 	const char *syms[] = { "___SUNW_dof", "__SUNW_dof" };
    577 	int i, fd = -1;
    578 
    579 	/*
    580 	 * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and
    581 	 * __SUNW_dof is for actively-loaded DOF sections. We try to force
    582 	 * in both types of DOF section since the process may not yet have
    583 	 * run the code to instantiate these providers.
    584 	 */
    585 	for (i = 0; i < 2; i++) {
    586 		if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym,
    587 		    &sip) != 0) {
    588 			continue;
    589 		}
    590 
    591 		if ((mname = strrchr(oname, '/')) == NULL)
    592 			mname = oname;
    593 		else
    594 			mname++;
    595 
    596 		dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname);
    597 
    598 		if (Pread(P, &e_type, sizeof (e_type), pmp->pr_vaddr +
    599 		    offsetof(Elf64_Ehdr, e_type)) != sizeof (e_type)) {
    600 			dt_dprintf("read of ELF header failed");
    601 			continue;
    602 		}
    603 
    604 		dh.dofhp_dof = sym.st_value;
    605 		dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr;
    606 		dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod),
    607 		    sip.prs_lmid, mname);
    608 
    609 #if defined(__FreeBSD__) || defined(__NetBSD__)
    610 		dh.dofhp_pid = proc_getpid(P);
    611 
    612 		if (fd == -1 &&
    613 		    (fd = open("/dev/dtrace/helper", O_RDWR, 0)) < 0) {
    614 			dt_dprintf("open of helper device failed: %s\n",
    615 			    strerror(errno));
    616 			return (-1); /* errno is set for us */
    617 		}
    618 
    619 		if (ioctl(fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0)
    620 			dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod);
    621 #else
    622 		if (fd == -1 &&
    623 		    (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) {
    624 			dt_dprintf("pr_open of helper device failed: %s\n",
    625 			    strerror(errno));
    626 			return (-1); /* errno is set for us */
    627 		}
    628 
    629 		if (pr_ioctl(P, fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0)
    630 			dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod);
    631 #endif
    632 	}
    633 
    634 	if (fd != -1)
    635 #if defined(__FreeBSD__) || defined(__NetBSD__)
    636 		(void) close(fd);
    637 #else
    638 		(void) pr_close(P, fd);
    639 #endif
    640 
    641 	return (0);
    642 }
    643 
    644 static int
    645 dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
    646     dt_pcb_t *pcb, dt_proc_t *dpr)
    647 {
    648 	struct ps_prochandle *P = dpr->dpr_proc;
    649 	int ret = 0;
    650 
    651 	assert(DT_MUTEX_HELD(&dpr->dpr_lock));
    652 	(void) Pupdate_maps(P);
    653 	if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) {
    654 		ret = -1;
    655 		(void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_USDT,
    656 		    "failed to instantiate probes for pid %d: %s",
    657 #ifdef illumos
    658 		    (int)Pstatus(P)->pr_pid, strerror(errno));
    659 #else
    660 		    (int)proc_getpid(P), strerror(errno));
    661 #endif
    662 	}
    663 
    664 	/*
    665 	 * Put the module name in its canonical form.
    666 	 */
    667 	(void) dt_pid_fix_mod(pdp, P);
    668 
    669 	return (ret);
    670 }
    671 
    672 static pid_t
    673 dt_pid_get_pid(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb,
    674     dt_proc_t *dpr)
    675 {
    676 	pid_t pid;
    677 	char *c, *last = NULL, *end;
    678 
    679 	for (c = &pdp->dtpd_provider[0]; *c != '\0'; c++) {
    680 		if (!isdigit((unsigned char)*c))
    681 			last = c;
    682 	}
    683 
    684 	if (last == NULL || (*(++last) == '\0')) {
    685 		(void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_BADPROV,
    686 		    "'%s' is not a valid provider", pdp->dtpd_provider);
    687 		return (-1);
    688 	}
    689 
    690 	errno = 0;
    691 	pid = strtol(last, &end, 10);
    692 
    693 	if (errno != 0 || end == last || end[0] != '\0' || pid <= 0) {
    694 		(void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_BADPID,
    695 		    "'%s' does not contain a valid pid", pdp->dtpd_provider);
    696 		return (-1);
    697 	}
    698 
    699 	return (pid);
    700 }
    701 
    702 int
    703 dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
    704 {
    705 	char provname[DTRACE_PROVNAMELEN];
    706 	struct ps_prochandle *P;
    707 	dt_proc_t *dpr;
    708 	pid_t pid;
    709 	int err = 0;
    710 
    711 	assert(pcb != NULL);
    712 
    713 	if ((pid = dt_pid_get_pid(pdp, dtp, pcb, NULL)) == -1)
    714 		return (-1);
    715 
    716 	if (dtp->dt_ftfd == -1) {
    717 		if (dtp->dt_fterr == ENOENT) {
    718 			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV,
    719 			    "pid provider is not installed on this system");
    720 		} else {
    721 			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV,
    722 			    "pid provider is not available: %s",
    723 			    strerror(dtp->dt_fterr));
    724 		}
    725 
    726 		return (-1);
    727 	}
    728 
    729 	(void) snprintf(provname, sizeof (provname), "pid%d", (int)pid);
    730 
    731 	if (gmatch(provname, pdp->dtpd_provider) != 0) {
    732 #if defined(__FreeBSD__) || defined(__NetBSD__)
    733 		if ((P = dt_proc_grab(dtp, pid, 0, 1)) == NULL)
    734 #else
    735 		if ((P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE,
    736 		    0)) == NULL)
    737 #endif
    738 		{
    739 			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB,
    740 			    "failed to grab process %d", (int)pid);
    741 			return (-1);
    742 		}
    743 
    744 		dpr = dt_proc_lookup(dtp, P, 0);
    745 		assert(dpr != NULL);
    746 		(void) pthread_mutex_lock(&dpr->dpr_lock);
    747 
    748 		if ((err = dt_pid_create_pid_probes(pdp, dtp, pcb, dpr)) == 0) {
    749 			/*
    750 			 * Alert other retained enablings which may match
    751 			 * against the newly created probes.
    752 			 */
    753 			(void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL);
    754 		}
    755 
    756 		(void) pthread_mutex_unlock(&dpr->dpr_lock);
    757 		dt_proc_release(dtp, P);
    758 	}
    759 
    760 	/*
    761 	 * If it's not strictly a pid provider, we might match a USDT provider.
    762 	 */
    763 	if (strcmp(provname, pdp->dtpd_provider) != 0) {
    764 		if ((P = dt_proc_grab(dtp, pid, 0, 1)) == NULL) {
    765 			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB,
    766 			    "failed to grab process %d", (int)pid);
    767 			return (-1);
    768 		}
    769 
    770 		dpr = dt_proc_lookup(dtp, P, 0);
    771 		assert(dpr != NULL);
    772 		(void) pthread_mutex_lock(&dpr->dpr_lock);
    773 
    774 		if (!dpr->dpr_usdt) {
    775 			err = dt_pid_create_usdt_probes(pdp, dtp, pcb, dpr);
    776 			dpr->dpr_usdt = B_TRUE;
    777 		}
    778 
    779 		(void) pthread_mutex_unlock(&dpr->dpr_lock);
    780 		dt_proc_release(dtp, P);
    781 	}
    782 
    783 	return (err ? -1 : 0);
    784 }
    785 
    786 int
    787 dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr)
    788 {
    789 	dtrace_enable_io_t args;
    790 	dtrace_prog_t *pgp;
    791 	dt_stmt_t *stp;
    792 	dtrace_probedesc_t *pdp, pd;
    793 	pid_t pid;
    794 	int ret = 0, found = B_FALSE;
    795 	char provname[DTRACE_PROVNAMELEN];
    796 
    797 	(void) snprintf(provname, sizeof (provname), "pid%d",
    798 	    (int)dpr->dpr_pid);
    799 
    800 	for (pgp = dt_list_next(&dtp->dt_programs); pgp != NULL;
    801 	    pgp = dt_list_next(pgp)) {
    802 
    803 		for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL;
    804 		    stp = dt_list_next(stp)) {
    805 
    806 			pdp = &stp->ds_desc->dtsd_ecbdesc->dted_probe;
    807 			pid = dt_pid_get_pid(pdp, dtp, NULL, dpr);
    808 			if (pid != dpr->dpr_pid)
    809 				continue;
    810 
    811 			found = B_TRUE;
    812 
    813 			pd = *pdp;
    814 
    815 			if (gmatch(provname, pdp->dtpd_provider) != 0 &&
    816 			    dt_pid_create_pid_probes(&pd, dtp, NULL, dpr) != 0)
    817 				ret = 1;
    818 
    819 			/*
    820 			 * If it's not strictly a pid provider, we might match
    821 			 * a USDT provider.
    822 			 */
    823 			if (strcmp(provname, pdp->dtpd_provider) != 0 &&
    824 			    dt_pid_create_usdt_probes(&pd, dtp, NULL, dpr) != 0)
    825 				ret = 1;
    826 		}
    827 	}
    828 
    829 	if (found) {
    830 		/*
    831 		 * Give DTrace a shot to the ribs to get it to check
    832 		 * out the newly created probes.
    833 		 */
    834 		args.dof = NULL;
    835 		args.n_matched = 0;
    836 		(void) dt_ioctl(dtp, DTRACEIOC_ENABLE, &args);
    837 	}
    838 
    839 	return (ret);
    840 }
    841 
    842 /*
    843  * libdtrace has a backroom deal with us to ask us for type information on
    844  * behalf of pid provider probes when fasttrap doesn't return any type
    845  * information. Instead we'll look up the module and see if there is type
    846  * information available. However, if there is no type information available due
    847  * to a lack of CTF data, then we want to make sure that DTrace still carries on
    848  * in face of that. As such we don't have a meaningful exit code about failure.
    849  * We emit information about why we failed to the dtrace debug log so someone
    850  * can figure it out by asking nicely for DTRACE_DEBUG.
    851  */
    852 void
    853 dt_pid_get_types(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
    854     dtrace_argdesc_t *adp, int *nargs)
    855 {
    856 	dt_module_t *dmp;
    857 	ctf_file_t *fp;
    858 	ctf_funcinfo_t f;
    859 	ctf_id_t argv[32];
    860 	GElf_Sym sym;
    861 	prsyminfo_t si;
    862 	struct ps_prochandle *p;
    863 	int i, args;
    864 	char buf[DTRACE_ARGTYPELEN];
    865 	const char *mptr;
    866 	char *eptr;
    867 	int ret = 0;
    868 	int argc = sizeof (argv) / sizeof (ctf_id_t);
    869 	Lmid_t lmid;
    870 
    871 	/* Set up a potential outcome */
    872 	args = *nargs;
    873 	*nargs = 0;
    874 
    875 	/*
    876 	 * If we don't have an entry or return probe then we can just stop right
    877 	 * now as we don't have arguments for offset probes.
    878 	 */
    879 	if (strcmp(pdp->dtpd_name, "entry") != 0 &&
    880 	    strcmp(pdp->dtpd_name, "return") != 0)
    881 		return;
    882 
    883 	dmp = dt_module_create(dtp, pdp->dtpd_provider);
    884 	if (dmp == NULL) {
    885 		dt_dprintf("failed to find module for %s\n",
    886 		    pdp->dtpd_provider);
    887 		return;
    888 	}
    889 	if (dt_module_load(dtp, dmp) != 0) {
    890 		dt_dprintf("failed to load module for %s\n",
    891 		    pdp->dtpd_provider);
    892 		return;
    893 	}
    894 
    895 	/*
    896 	 * We may be working with a module that doesn't have ctf. If that's the
    897 	 * case then we just return now and move on with life.
    898 	 */
    899 	fp = dt_module_getctflib(dtp, dmp, pdp->dtpd_mod);
    900 	if (fp == NULL) {
    901 		dt_dprintf("no ctf container for  %s\n",
    902 		    pdp->dtpd_mod);
    903 		return;
    904 	}
    905 	p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
    906 	if (p == NULL) {
    907 		dt_dprintf("failed to grab pid\n");
    908 		return;
    909 	}
    910 	dt_proc_lock(dtp, p);
    911 
    912 	/*
    913 	 * Check to see if the D module has a link map ID and separate that out
    914 	 * for properly interrogating libproc.
    915 	 */
    916 	if ((mptr = strchr(pdp->dtpd_mod, '`')) != NULL) {
    917 		if (strlen(pdp->dtpd_mod) < 3) {
    918 			dt_dprintf("found weird modname with linkmap, "
    919 			    "aborting: %s\n", pdp->dtpd_mod);
    920 			goto out;
    921 		}
    922 		if (pdp->dtpd_mod[0] != 'L' || pdp->dtpd_mod[1] != 'M') {
    923 			dt_dprintf("missing leading 'LM', "
    924 			    "aborting: %s\n", pdp->dtpd_mod);
    925 			goto out;
    926 		}
    927 		errno = 0;
    928 		lmid = strtol(pdp->dtpd_mod + 2, &eptr, 16);
    929 		if (errno == ERANGE || eptr != mptr) {
    930 			dt_dprintf("failed to parse out lmid, aborting: %s\n",
    931 			    pdp->dtpd_mod);
    932 			goto out;
    933 		}
    934 		mptr++;
    935 	} else {
    936 		mptr = pdp->dtpd_mod;
    937 		lmid = 0;
    938 	}
    939 
    940 	if (Pxlookup_by_name(p, lmid, mptr, pdp->dtpd_func,
    941 	    &sym, &si) != 0) {
    942 		dt_dprintf("failed to find function %s in %s`%s\n",
    943 		    pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
    944 		goto out;
    945 	}
    946 	if (ctf_func_info(fp, si.prs_id, &f) == CTF_ERR) {
    947 		dt_dprintf("failed to get ctf information for %s in %s`%s\n",
    948 		    pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
    949 		goto out;
    950 	}
    951 
    952 	(void) snprintf(buf, sizeof (buf), "%s`%s", pdp->dtpd_provider,
    953 	    pdp->dtpd_mod);
    954 
    955 	if (strcmp(pdp->dtpd_name, "return") == 0) {
    956 		if (args < 2)
    957 			goto out;
    958 
    959 		bzero(adp, sizeof (dtrace_argdesc_t));
    960 		adp->dtargd_ndx = 0;
    961 		adp->dtargd_id = pdp->dtpd_id;
    962 		adp->dtargd_mapping = adp->dtargd_ndx;
    963 		/*
    964 		 * We explicitly leave out the library here, we only care that
    965 		 * it is some int. We are assuming that there is no ctf
    966 		 * container in here that is lying about what an int is.
    967 		 */
    968 		(void) snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
    969 		    "user %s`%s", pdp->dtpd_provider, "int");
    970 		adp++;
    971 		bzero(adp, sizeof (dtrace_argdesc_t));
    972 		adp->dtargd_ndx = 1;
    973 		adp->dtargd_id = pdp->dtpd_id;
    974 		adp->dtargd_mapping = adp->dtargd_ndx;
    975 		ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
    976 		    "userland ");
    977 		(void) ctf_type_qname(fp, f.ctc_return, adp->dtargd_native +
    978 		    ret, DTRACE_ARGTYPELEN - ret, buf);
    979 		*nargs = 2;
    980 	} else {
    981 		if (ctf_func_args(fp, si.prs_id, argc, argv) == CTF_ERR)
    982 			goto out;
    983 
    984 		*nargs = MIN(args, f.ctc_argc);
    985 		for (i = 0; i < *nargs; i++, adp++) {
    986 			bzero(adp, sizeof (dtrace_argdesc_t));
    987 			adp->dtargd_ndx = i;
    988 			adp->dtargd_id = pdp->dtpd_id;
    989 			adp->dtargd_mapping = adp->dtargd_ndx;
    990 			ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
    991 			    "userland ");
    992 			(void) ctf_type_qname(fp, argv[i], adp->dtargd_native +
    993 			    ret, DTRACE_ARGTYPELEN - ret, buf);
    994 		}
    995 	}
    996 out:
    997 	dt_proc_unlock(dtp, p);
    998 	dt_proc_release(dtp, p);
    999 }
   1000