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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
38 #include <dt_program.h>
40 #include <dt_string.h>
42 typedef struct dt_pid_probe
{
43 dtrace_hdl_t
*dpp_dtp
;
46 struct ps_prochandle
*dpp_pr
;
55 uint64_t dpp_stret
[4];
57 uint_t dpp_last_taken
;
61 * Compose the lmid and object name into the canonical representation. We
62 * omit the lmid for the default link map for convenience.
65 dt_pid_objname(char *buf
, size_t len
, Lmid_t lmid
, const char *obj
)
67 if (lmid
== LM_ID_BASE
)
68 (void) strncpy(buf
, obj
, len
);
70 (void) snprintf(buf
, len
, "LM%lx`%s", lmid
, obj
);
74 dt_pid_error(dtrace_hdl_t
*dtp
, dt_pcb_t
*pcb
, dt_proc_t
*dpr
,
75 fasttrap_probe_spec_t
*ftp
, dt_errtag_t tag
, const char *fmt
, ...)
86 len
= vsnprintf(dpr
->dpr_errmsg
, sizeof (dpr
->dpr_errmsg
),
89 if (dpr
->dpr_errmsg
[len
- 2] == '\n')
90 dpr
->dpr_errmsg
[len
- 2] = '\0';
92 dt_set_errmsg(dtp
, dt_errtag(tag
), pcb
->pcb_region
,
93 pcb
->pcb_filetag
, pcb
->pcb_fileptr
? yylineno
: 0, fmt
, ap
);
101 dt_pid_per_sym(dt_pid_probe_t
*pp
, const GElf_Sym
*symp
, const char *func
)
103 dtrace_hdl_t
*dtp
= pp
->dpp_dtp
;
104 dt_pcb_t
*pcb
= pp
->dpp_pcb
;
105 dt_proc_t
*dpr
= pp
->dpp_dpr
;
106 fasttrap_probe_spec_t
*ftp
;
112 int isdash
= strcmp("-", func
) == 0;
115 pid
= Pstatus(pp
->dpp_pr
)->pr_pid
;
117 dt_dprintf("creating probe pid%d:%s:%s:%s\n", (int)pid
, pp
->dpp_obj
,
120 sz
= sizeof (fasttrap_probe_spec_t
) + (isdash
? 4 :
121 (symp
->st_size
- 1) * sizeof (ftp
->ftps_offs
[0]));
123 if ((ftp
= dt_alloc(dtp
, sz
)) == NULL
) {
124 dt_dprintf("proc_per_sym: dt_alloc(%lu) failed\n", sz
);
125 return (1); /* errno is set for us */
129 (void) strncpy(ftp
->ftps_func
, func
, sizeof (ftp
->ftps_func
));
131 dt_pid_objname(ftp
->ftps_mod
, sizeof (ftp
->ftps_mod
), pp
->dpp_lmid
,
134 if (!isdash
&& gmatch("return", pp
->dpp_name
)) {
135 if (dt_pid_create_return_probe(pp
->dpp_pr
, dtp
, ftp
, symp
,
136 pp
->dpp_stret
) < 0) {
137 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
138 D_PROC_CREATEFAIL
, "failed to create return probe "
139 "for '%s': %s", func
,
140 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
146 if (!isdash
&& gmatch("entry", pp
->dpp_name
)) {
147 if (dt_pid_create_entry_probe(pp
->dpp_pr
, dtp
, ftp
, symp
) < 0) {
148 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
149 D_PROC_CREATEFAIL
, "failed to create entry probe "
150 "for '%s': %s", func
,
151 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
157 glob
= strisglob(pp
->dpp_name
);
158 if (!glob
&& nmatches
== 0) {
159 off
= strtoull(pp
->dpp_name
, &end
, 16);
161 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
, D_PROC_NAME
,
162 "'%s' is an invalid probe name", pp
->dpp_name
));
165 if (off
>= symp
->st_size
) {
166 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
, D_PROC_OFF
,
167 "offset 0x%llx outside of function '%s'",
168 (u_longlong_t
)off
, func
));
171 err
= dt_pid_create_offset_probe(pp
->dpp_pr
, pp
->dpp_dtp
, ftp
,
174 if (err
== DT_PROC_ERR
) {
175 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
176 D_PROC_CREATEFAIL
, "failed to create probe at "
177 "'%s+0x%llx': %s", func
, (u_longlong_t
)off
,
178 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
181 if (err
== DT_PROC_ALIGN
) {
182 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
, D_PROC_ALIGN
,
183 "offset 0x%llx is not aligned on an instruction",
189 } else if (glob
&& !isdash
) {
190 if (dt_pid_create_glob_offset_probes(pp
->dpp_pr
,
191 pp
->dpp_dtp
, ftp
, symp
, pp
->dpp_name
) < 0) {
192 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
194 "failed to create offset probes in '%s': %s", func
,
195 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
201 pp
->dpp_nmatches
+= nmatches
;
209 dt_pid_sym_filt(void *arg
, const GElf_Sym
*symp
, const char *func
)
211 dt_pid_probe_t
*pp
= arg
;
213 if (symp
->st_shndx
== SHN_UNDEF
)
216 if (symp
->st_size
== 0) {
217 dt_dprintf("st_size of %s is zero\n", func
);
221 if (pp
->dpp_last_taken
== 0 ||
222 symp
->st_value
!= pp
->dpp_last
.st_value
||
223 symp
->st_size
!= pp
->dpp_last
.st_size
) {
225 * Due to 4524008, _init and _fini may have a bloated st_size.
226 * While this bug has been fixed for a while, old binaries
227 * may exist that still exhibit this problem. As a result, we
228 * don't match _init and _fini though we allow users to
229 * specify them explicitly.
231 if (strcmp(func
, "_init") == 0 || strcmp(func
, "_fini") == 0)
234 if ((pp
->dpp_last_taken
= gmatch(func
, pp
->dpp_func
)) != 0) {
235 pp
->dpp_last
= *symp
;
236 return (dt_pid_per_sym(pp
, symp
, func
));
244 dt_pid_per_mod(void *arg
, const prmap_t
*pmp
, const char *obj
)
246 dt_pid_probe_t
*pp
= arg
;
247 dtrace_hdl_t
*dtp
= pp
->dpp_dtp
;
248 dt_pcb_t
*pcb
= pp
->dpp_pcb
;
249 dt_proc_t
*dpr
= pp
->dpp_dpr
;
255 (void) Plmid(pp
->dpp_pr
, pmp
->pr_vaddr
, &pp
->dpp_lmid
);
257 if ((pp
->dpp_obj
= strrchr(obj
, '/')) == NULL
)
262 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret1", &sym
,
264 pp
->dpp_stret
[0] = sym
.st_value
;
266 pp
->dpp_stret
[0] = 0;
268 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret2", &sym
,
270 pp
->dpp_stret
[1] = sym
.st_value
;
272 pp
->dpp_stret
[1] = 0;
274 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret4", &sym
,
276 pp
->dpp_stret
[2] = sym
.st_value
;
278 pp
->dpp_stret
[2] = 0;
280 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret8", &sym
,
282 pp
->dpp_stret
[3] = sym
.st_value
;
284 pp
->dpp_stret
[3] = 0;
286 dt_dprintf("%s stret %llx %llx %llx %llx\n", obj
,
287 (u_longlong_t
)pp
->dpp_stret
[0], (u_longlong_t
)pp
->dpp_stret
[1],
288 (u_longlong_t
)pp
->dpp_stret
[2], (u_longlong_t
)pp
->dpp_stret
[3]);
291 * If pp->dpp_func contains any globbing meta-characters, we need
292 * to iterate over the symbol table and compare each function name
293 * against the pattern.
295 if (!strisglob(pp
->dpp_func
)) {
297 * If we fail to lookup the symbol, try interpreting the
298 * function as the special "-" function that indicates that the
299 * probe name should be interpreted as a absolute virtual
300 * address. If that fails and we were matching a specific
301 * function in a specific module, report the error, otherwise
302 * just fail silently in the hopes that some other object will
303 * contain the desired symbol.
305 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
,
306 pp
->dpp_func
, &sym
, NULL
) != 0) {
307 if (strcmp("-", pp
->dpp_func
) == 0) {
310 GELF_ST_INFO(STB_LOCAL
, STT_FUNC
);
313 sym
.st_size
= Pstatus(pp
->dpp_pr
)->pr_dmodel
==
314 PR_MODEL_ILP32
? -1U : -1ULL;
316 } else if (!strisglob(pp
->dpp_mod
)) {
317 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
,
319 "failed to lookup '%s' in module '%s'",
320 pp
->dpp_func
, pp
->dpp_mod
));
327 * Only match defined functions of non-zero size.
329 if (GELF_ST_TYPE(sym
.st_info
) != STT_FUNC
||
330 sym
.st_shndx
== SHN_UNDEF
|| sym
.st_size
== 0)
334 * We don't instrument PLTs -- they're dynamically rewritten,
335 * and, so, inherently dicey to instrument.
337 if (Ppltdest(pp
->dpp_pr
, sym
.st_value
) != NULL
)
340 (void) Plookup_by_addr(pp
->dpp_pr
, sym
.st_value
, pp
->dpp_func
,
341 DTRACE_FUNCNAMELEN
, &sym
);
343 return (dt_pid_per_sym(pp
, &sym
, pp
->dpp_func
));
345 uint_t nmatches
= pp
->dpp_nmatches
;
347 if (Psymbol_iter_by_addr(pp
->dpp_pr
, obj
, PR_SYMTAB
,
348 BIND_ANY
| TYPE_FUNC
, dt_pid_sym_filt
, pp
) == 1)
351 if (nmatches
== pp
->dpp_nmatches
) {
353 * If we didn't match anything in the PR_SYMTAB, try
356 if (Psymbol_iter_by_addr(pp
->dpp_pr
, obj
, PR_DYNSYM
,
357 BIND_ANY
| TYPE_FUNC
, dt_pid_sym_filt
, pp
) == 1)
366 dt_pid_mod_filt(void *arg
, const prmap_t
*pmp
, const char *obj
)
368 char name
[DTRACE_MODNAMELEN
];
369 dt_pid_probe_t
*pp
= arg
;
371 if ((pp
->dpp_obj
= strrchr(obj
, '/')) == NULL
)
376 if (gmatch(pp
->dpp_obj
, pp
->dpp_mod
))
377 return (dt_pid_per_mod(pp
, pmp
, obj
));
379 (void) Plmid(pp
->dpp_pr
, pmp
->pr_vaddr
, &pp
->dpp_lmid
);
381 dt_pid_objname(name
, sizeof (name
), pp
->dpp_lmid
, pp
->dpp_obj
);
383 if (gmatch(name
, pp
->dpp_mod
))
384 return (dt_pid_per_mod(pp
, pmp
, obj
));
389 static const prmap_t
*
390 dt_pid_fix_mod(dtrace_probedesc_t
*pdp
, struct ps_prochandle
*P
)
393 Lmid_t lmid
= PR_LMID_EVERY
;
398 * Pick apart the link map from the library name.
400 if (strchr(pdp
->dtpd_mod
, '`') != NULL
) {
403 if (strncmp(pdp
->dtpd_mod
, "LM", 2) != 0 ||
404 !isdigit(pdp
->dtpd_mod
[2]))
407 lmid
= strtoul(&pdp
->dtpd_mod
[2], &end
, 16);
411 if (*end
!= '`' || strchr(obj
, '`') != NULL
)
418 if ((pmp
= Plmid_to_map(P
, lmid
, obj
)) == NULL
)
421 (void) Pobjname(P
, pmp
->pr_vaddr
, m
, sizeof (m
));
422 if ((obj
= strrchr(m
, '/')) == NULL
)
427 (void) Plmid(P
, pmp
->pr_vaddr
, &lmid
);
428 dt_pid_objname(pdp
->dtpd_mod
, sizeof (pdp
->dtpd_mod
), lmid
, obj
);
435 dt_pid_create_pid_probes(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
,
436 dt_pcb_t
*pcb
, dt_proc_t
*dpr
)
443 pp
.dpp_pr
= dpr
->dpr_proc
;
447 * We can only trace dynamically-linked executables (since we've
448 * hidden some magic in ld.so.1 as well as libc.so.1).
450 if (Pname_to_map(pp
.dpp_pr
, PR_OBJ_LDSO
) == NULL
) {
451 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_DYN
,
452 "process %s is not a dynamically-linked executable",
453 &pdp
->dtpd_provider
[3]));
456 pp
.dpp_mod
= pdp
->dtpd_mod
[0] != '\0' ? pdp
->dtpd_mod
: "*";
457 pp
.dpp_func
= pdp
->dtpd_func
[0] != '\0' ? pdp
->dtpd_func
: "*";
458 pp
.dpp_name
= pdp
->dtpd_name
[0] != '\0' ? pdp
->dtpd_name
: "*";
459 pp
.dpp_last_taken
= 0;
461 if (strcmp(pp
.dpp_func
, "-") == 0) {
462 const prmap_t
*aout
, *pmp
;
464 if (pdp
->dtpd_mod
[0] == '\0') {
465 pp
.dpp_mod
= pdp
->dtpd_mod
;
466 (void) strcpy(pdp
->dtpd_mod
, "a.out");
467 } else if (strisglob(pp
.dpp_mod
) ||
468 (aout
= Pname_to_map(pp
.dpp_pr
, "a.out")) == NULL
||
469 (pmp
= Pname_to_map(pp
.dpp_pr
, pp
.dpp_mod
)) == NULL
||
470 aout
->pr_vaddr
!= pmp
->pr_vaddr
) {
471 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_LIB
,
472 "only the a.out module is valid with the "
476 if (strisglob(pp
.dpp_name
)) {
477 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_NAME
,
478 "only individual addresses may be specified "
479 "with the '-' function"));
484 * If pp.dpp_mod contains any globbing meta-characters, we need
485 * to iterate over each module and compare its name against the
486 * pattern. An empty module name is treated as '*'.
488 if (strisglob(pp
.dpp_mod
)) {
489 ret
= Pobject_iter(pp
.dpp_pr
, dt_pid_mod_filt
, &pp
);
495 * If we can't find a matching module, don't sweat it -- either
496 * we'll fail the enabling because the probes don't exist or
497 * we'll wait for that module to come along.
499 if ((pmp
= dt_pid_fix_mod(pdp
, pp
.dpp_pr
)) != NULL
) {
500 if ((obj
= strchr(pdp
->dtpd_mod
, '`')) == NULL
)
505 ret
= dt_pid_per_mod(&pp
, pmp
, obj
);
513 dt_pid_usdt_mapping(void *data
, const prmap_t
*pmp
, const char *oname
)
515 struct ps_prochandle
*P
= data
;
521 const char *syms
[] = { "___SUNW_dof", "__SUNW_dof" };
525 * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and
526 * __SUNW_dof is for actively-loaded DOF sections. We try to force
527 * in both types of DOF section since the process may not yet have
528 * run the code to instantiate these providers.
530 for (i
= 0; i
< 2; i
++) {
531 if (Pxlookup_by_name(P
, PR_LMID_EVERY
, oname
, syms
[i
], &sym
,
536 if ((mname
= strrchr(oname
, '/')) == NULL
)
541 dt_dprintf("lookup of %s succeeded for %s\n", syms
[i
], mname
);
543 if (Pread(P
, &e_type
, sizeof (e_type
), pmp
->pr_vaddr
+
544 offsetof(Elf64_Ehdr
, e_type
)) != sizeof (e_type
)) {
545 dt_dprintf("read of ELF header failed");
549 dh
.dofhp_dof
= sym
.st_value
;
550 dh
.dofhp_addr
= (e_type
== ET_EXEC
) ? 0 : pmp
->pr_vaddr
;
552 dt_pid_objname(dh
.dofhp_mod
, sizeof (dh
.dofhp_mod
),
553 sip
.prs_lmid
, mname
);
556 (fd
= pr_open(P
, "/dev/dtrace/helper", O_RDWR
, 0)) < 0) {
557 dt_dprintf("pr_open of helper device failed: %s\n",
559 return (-1); /* errno is set for us */
562 if (pr_ioctl(P
, fd
, DTRACEHIOC_ADDDOF
, &dh
, sizeof (dh
)) < 0)
563 dt_dprintf("DOF was rejected for %s\n", dh
.dofhp_mod
);
567 (void) pr_close(P
, fd
);
573 dt_pid_create_usdt_probes(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
,
574 dt_pcb_t
*pcb
, dt_proc_t
*dpr
)
576 struct ps_prochandle
*P
= dpr
->dpr_proc
;
579 assert(DT_MUTEX_HELD(&dpr
->dpr_lock
));
581 (void) Pupdate_maps(P
);
582 if (Pobject_iter(P
, dt_pid_usdt_mapping
, P
) != 0) {
584 (void) dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_USDT
,
585 "failed to instantiate probes for pid %d: %s",
586 (int)Pstatus(P
)->pr_pid
, strerror(errno
));
590 * Put the module name in its canonical form.
592 (void) dt_pid_fix_mod(pdp
, P
);
598 dt_pid_get_pid(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
, dt_pcb_t
*pcb
,
602 char *c
, *last
= NULL
, *end
;
604 for (c
= &pdp
->dtpd_provider
[0]; *c
!= '\0'; c
++) {
609 if (last
== NULL
|| (*(++last
) == '\0')) {
610 (void) dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_BADPROV
,
611 "'%s' is not a valid provider", pdp
->dtpd_provider
);
616 pid
= strtol(last
, &end
, 10);
618 if (errno
!= 0 || end
== last
|| end
[0] != '\0' || pid
<= 0) {
619 (void) dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_BADPID
,
620 "'%s' does not contain a valid pid", pdp
->dtpd_provider
);
628 dt_pid_create_probes(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
, dt_pcb_t
*pcb
)
630 char provname
[DTRACE_PROVNAMELEN
];
631 struct ps_prochandle
*P
;
638 if ((pid
= dt_pid_get_pid(pdp
, dtp
, pcb
, NULL
)) == -1)
641 if (dtp
->dt_ftfd
== -1) {
642 if (dtp
->dt_fterr
== ENOENT
) {
643 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_NODEV
,
644 "pid provider is not installed on this system");
646 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_NODEV
,
647 "pid provider is not available: %s",
648 strerror(dtp
->dt_fterr
));
654 (void) snprintf(provname
, sizeof (provname
), "pid%d", (int)pid
);
656 if (gmatch(provname
, pdp
->dtpd_provider
) != 0) {
657 if ((P
= dt_proc_grab(dtp
, pid
, PGRAB_RDONLY
| PGRAB_FORCE
,
659 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_GRAB
,
660 "failed to grab process %d", (int)pid
);
664 dpr
= dt_proc_lookup(dtp
, P
, 0);
666 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
668 if ((err
= dt_pid_create_pid_probes(pdp
, dtp
, pcb
, dpr
)) == 0) {
670 * Alert other retained enablings which may match
671 * against the newly created probes.
673 (void) dt_ioctl(dtp
, DTRACEIOC_ENABLE
, NULL
);
676 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
677 dt_proc_release(dtp
, P
);
681 * If it's not strictly a pid provider, we might match a USDT provider.
683 if (strcmp(provname
, pdp
->dtpd_provider
) != 0) {
684 if ((P
= dt_proc_grab(dtp
, pid
, 0, 1)) == NULL
) {
685 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_GRAB
,
686 "failed to grab process %d", (int)pid
);
690 dpr
= dt_proc_lookup(dtp
, P
, 0);
692 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
694 if (!dpr
->dpr_usdt
) {
695 err
= dt_pid_create_usdt_probes(pdp
, dtp
, pcb
, dpr
);
696 dpr
->dpr_usdt
= B_TRUE
;
699 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
700 dt_proc_release(dtp
, P
);
703 return (err
? -1 : 0);
707 dt_pid_create_probes_module(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
)
711 dtrace_probedesc_t
*pdp
, pd
;
713 int ret
= 0, found
= B_FALSE
;
714 char provname
[DTRACE_PROVNAMELEN
];
716 (void) snprintf(provname
, sizeof (provname
), "pid%d",
719 for (pgp
= dt_list_next(&dtp
->dt_programs
); pgp
!= NULL
;
720 pgp
= dt_list_next(pgp
)) {
722 for (stp
= dt_list_next(&pgp
->dp_stmts
); stp
!= NULL
;
723 stp
= dt_list_next(stp
)) {
725 pdp
= &stp
->ds_desc
->dtsd_ecbdesc
->dted_probe
;
726 pid
= dt_pid_get_pid(pdp
, dtp
, NULL
, dpr
);
727 if (pid
!= dpr
->dpr_pid
)
734 if (gmatch(provname
, pdp
->dtpd_provider
) != 0 &&
735 dt_pid_create_pid_probes(&pd
, dtp
, NULL
, dpr
) != 0)
739 * If it's not strictly a pid provider, we might match
742 if (strcmp(provname
, pdp
->dtpd_provider
) != 0 &&
743 dt_pid_create_usdt_probes(&pd
, dtp
, NULL
, dpr
) != 0)
750 * Give DTrace a shot to the ribs to get it to check
751 * out the newly created probes.
753 (void) dt_ioctl(dtp
, DTRACEIOC_ENABLE
, NULL
);