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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
39 #include <sys/sysmacros.h>
42 #include <dt_program.h>
44 #include <dt_string.h>
45 #include <dt_module.h>
47 typedef struct dt_pid_probe
{
48 dtrace_hdl_t
*dpp_dtp
;
51 struct ps_prochandle
*dpp_pr
;
60 uint64_t dpp_stret
[4];
62 uint_t dpp_last_taken
;
66 * Compose the lmid and object name into the canonical representation. We
67 * omit the lmid for the default link map for convenience.
70 dt_pid_objname(char *buf
, size_t len
, Lmid_t lmid
, const char *obj
)
72 if (lmid
== LM_ID_BASE
)
73 (void) strncpy(buf
, obj
, len
);
75 (void) snprintf(buf
, len
, "LM%lx`%s", lmid
, obj
);
79 dt_pid_error(dtrace_hdl_t
*dtp
, dt_pcb_t
*pcb
, dt_proc_t
*dpr
,
80 fasttrap_probe_spec_t
*ftp
, dt_errtag_t tag
, const char *fmt
, ...)
91 len
= vsnprintf(dpr
->dpr_errmsg
, sizeof (dpr
->dpr_errmsg
),
94 if (dpr
->dpr_errmsg
[len
- 2] == '\n')
95 dpr
->dpr_errmsg
[len
- 2] = '\0';
97 dt_set_errmsg(dtp
, dt_errtag(tag
), pcb
->pcb_region
,
98 pcb
->pcb_filetag
, pcb
->pcb_fileptr
? yylineno
: 0, fmt
, ap
);
106 dt_pid_per_sym(dt_pid_probe_t
*pp
, const GElf_Sym
*symp
, const char *func
)
108 dtrace_hdl_t
*dtp
= pp
->dpp_dtp
;
109 dt_pcb_t
*pcb
= pp
->dpp_pcb
;
110 dt_proc_t
*dpr
= pp
->dpp_dpr
;
111 fasttrap_probe_spec_t
*ftp
;
117 int isdash
= strcmp("-", func
) == 0;
120 pid
= Pstatus(pp
->dpp_pr
)->pr_pid
;
122 dt_dprintf("creating probe pid%d:%s:%s:%s\n", (int)pid
, pp
->dpp_obj
,
125 sz
= sizeof (fasttrap_probe_spec_t
) + (isdash
? 4 :
126 (symp
->st_size
- 1) * sizeof (ftp
->ftps_offs
[0]));
128 if ((ftp
= dt_alloc(dtp
, sz
)) == NULL
) {
129 dt_dprintf("proc_per_sym: dt_alloc(%lu) failed\n", sz
);
130 return (1); /* errno is set for us */
134 (void) strncpy(ftp
->ftps_func
, func
, sizeof (ftp
->ftps_func
));
136 dt_pid_objname(ftp
->ftps_mod
, sizeof (ftp
->ftps_mod
), pp
->dpp_lmid
,
139 if (!isdash
&& gmatch("return", pp
->dpp_name
)) {
140 if (dt_pid_create_return_probe(pp
->dpp_pr
, dtp
, ftp
, symp
,
141 pp
->dpp_stret
) < 0) {
142 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
143 D_PROC_CREATEFAIL
, "failed to create return probe "
144 "for '%s': %s", func
,
145 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
151 if (!isdash
&& gmatch("entry", pp
->dpp_name
)) {
152 if (dt_pid_create_entry_probe(pp
->dpp_pr
, dtp
, ftp
, symp
) < 0) {
153 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
154 D_PROC_CREATEFAIL
, "failed to create entry probe "
155 "for '%s': %s", func
,
156 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
162 glob
= strisglob(pp
->dpp_name
);
163 if (!glob
&& nmatches
== 0) {
164 off
= strtoull(pp
->dpp_name
, &end
, 16);
166 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
, D_PROC_NAME
,
167 "'%s' is an invalid probe name", pp
->dpp_name
));
170 if (off
>= symp
->st_size
) {
171 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
, D_PROC_OFF
,
172 "offset 0x%llx outside of function '%s'",
173 (u_longlong_t
)off
, func
));
176 err
= dt_pid_create_offset_probe(pp
->dpp_pr
, pp
->dpp_dtp
, ftp
,
179 if (err
== DT_PROC_ERR
) {
180 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
181 D_PROC_CREATEFAIL
, "failed to create probe at "
182 "'%s+0x%llx': %s", func
, (u_longlong_t
)off
,
183 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
186 if (err
== DT_PROC_ALIGN
) {
187 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
, D_PROC_ALIGN
,
188 "offset 0x%llx is not aligned on an instruction",
194 } else if (glob
&& !isdash
) {
195 if (dt_pid_create_glob_offset_probes(pp
->dpp_pr
,
196 pp
->dpp_dtp
, ftp
, symp
, pp
->dpp_name
) < 0) {
197 return (dt_pid_error(dtp
, pcb
, dpr
, ftp
,
199 "failed to create offset probes in '%s': %s", func
,
200 dtrace_errmsg(dtp
, dtrace_errno(dtp
))));
206 pp
->dpp_nmatches
+= nmatches
;
214 dt_pid_sym_filt(void *arg
, const GElf_Sym
*symp
, const char *func
)
216 dt_pid_probe_t
*pp
= arg
;
218 if (symp
->st_shndx
== SHN_UNDEF
)
221 if (symp
->st_size
== 0) {
222 dt_dprintf("st_size of %s is zero\n", func
);
226 if (pp
->dpp_last_taken
== 0 ||
227 symp
->st_value
!= pp
->dpp_last
.st_value
||
228 symp
->st_size
!= pp
->dpp_last
.st_size
) {
230 * Due to 4524008, _init and _fini may have a bloated st_size.
231 * While this bug has been fixed for a while, old binaries
232 * may exist that still exhibit this problem. As a result, we
233 * don't match _init and _fini though we allow users to
234 * specify them explicitly.
236 if (strcmp(func
, "_init") == 0 || strcmp(func
, "_fini") == 0)
239 if ((pp
->dpp_last_taken
= gmatch(func
, pp
->dpp_func
)) != 0) {
240 pp
->dpp_last
= *symp
;
241 return (dt_pid_per_sym(pp
, symp
, func
));
249 dt_pid_per_mod(void *arg
, const prmap_t
*pmp
, const char *obj
)
251 dt_pid_probe_t
*pp
= arg
;
252 dtrace_hdl_t
*dtp
= pp
->dpp_dtp
;
253 dt_pcb_t
*pcb
= pp
->dpp_pcb
;
254 dt_proc_t
*dpr
= pp
->dpp_dpr
;
260 (void) Plmid(pp
->dpp_pr
, pmp
->pr_vaddr
, &pp
->dpp_lmid
);
262 if ((pp
->dpp_obj
= strrchr(obj
, '/')) == NULL
)
267 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret1", &sym
,
269 pp
->dpp_stret
[0] = sym
.st_value
;
271 pp
->dpp_stret
[0] = 0;
273 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret2", &sym
,
275 pp
->dpp_stret
[1] = sym
.st_value
;
277 pp
->dpp_stret
[1] = 0;
279 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret4", &sym
,
281 pp
->dpp_stret
[2] = sym
.st_value
;
283 pp
->dpp_stret
[2] = 0;
285 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
, ".stret8", &sym
,
287 pp
->dpp_stret
[3] = sym
.st_value
;
289 pp
->dpp_stret
[3] = 0;
291 dt_dprintf("%s stret %llx %llx %llx %llx\n", obj
,
292 (u_longlong_t
)pp
->dpp_stret
[0], (u_longlong_t
)pp
->dpp_stret
[1],
293 (u_longlong_t
)pp
->dpp_stret
[2], (u_longlong_t
)pp
->dpp_stret
[3]);
296 * If pp->dpp_func contains any globbing meta-characters, we need
297 * to iterate over the symbol table and compare each function name
298 * against the pattern.
300 if (!strisglob(pp
->dpp_func
)) {
302 * If we fail to lookup the symbol, try interpreting the
303 * function as the special "-" function that indicates that the
304 * probe name should be interpreted as a absolute virtual
305 * address. If that fails and we were matching a specific
306 * function in a specific module, report the error, otherwise
307 * just fail silently in the hopes that some other object will
308 * contain the desired symbol.
310 if (Pxlookup_by_name(pp
->dpp_pr
, pp
->dpp_lmid
, obj
,
311 pp
->dpp_func
, &sym
, NULL
) != 0) {
312 if (strcmp("-", pp
->dpp_func
) == 0) {
315 GELF_ST_INFO(STB_LOCAL
, STT_FUNC
);
318 sym
.st_size
= Pstatus(pp
->dpp_pr
)->pr_dmodel
==
319 PR_MODEL_ILP32
? -1U : -1ULL;
321 } else if (!strisglob(pp
->dpp_mod
)) {
322 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
,
324 "failed to lookup '%s' in module '%s'",
325 pp
->dpp_func
, pp
->dpp_mod
));
332 * Only match defined functions of non-zero size.
334 if (GELF_ST_TYPE(sym
.st_info
) != STT_FUNC
||
335 sym
.st_shndx
== SHN_UNDEF
|| sym
.st_size
== 0)
339 * We don't instrument PLTs -- they're dynamically rewritten,
340 * and, so, inherently dicey to instrument.
342 if (Ppltdest(pp
->dpp_pr
, sym
.st_value
) != NULL
)
345 (void) Plookup_by_addr(pp
->dpp_pr
, sym
.st_value
, pp
->dpp_func
,
346 DTRACE_FUNCNAMELEN
, &sym
);
348 return (dt_pid_per_sym(pp
, &sym
, pp
->dpp_func
));
350 uint_t nmatches
= pp
->dpp_nmatches
;
352 if (Psymbol_iter_by_addr(pp
->dpp_pr
, obj
, PR_SYMTAB
,
353 BIND_ANY
| TYPE_FUNC
, dt_pid_sym_filt
, pp
) == 1)
356 if (nmatches
== pp
->dpp_nmatches
) {
358 * If we didn't match anything in the PR_SYMTAB, try
361 if (Psymbol_iter_by_addr(pp
->dpp_pr
, obj
, PR_DYNSYM
,
362 BIND_ANY
| TYPE_FUNC
, dt_pid_sym_filt
, pp
) == 1)
371 dt_pid_mod_filt(void *arg
, const prmap_t
*pmp
, const char *obj
)
373 char name
[DTRACE_MODNAMELEN
];
374 dt_pid_probe_t
*pp
= arg
;
376 if ((pp
->dpp_obj
= strrchr(obj
, '/')) == NULL
)
381 if (gmatch(pp
->dpp_obj
, pp
->dpp_mod
))
382 return (dt_pid_per_mod(pp
, pmp
, obj
));
384 (void) Plmid(pp
->dpp_pr
, pmp
->pr_vaddr
, &pp
->dpp_lmid
);
386 dt_pid_objname(name
, sizeof (name
), pp
->dpp_lmid
, pp
->dpp_obj
);
388 if (gmatch(name
, pp
->dpp_mod
))
389 return (dt_pid_per_mod(pp
, pmp
, obj
));
394 static const prmap_t
*
395 dt_pid_fix_mod(dtrace_probedesc_t
*pdp
, struct ps_prochandle
*P
)
398 Lmid_t lmid
= PR_LMID_EVERY
;
403 * Pick apart the link map from the library name.
405 if (strchr(pdp
->dtpd_mod
, '`') != NULL
) {
408 if (strncmp(pdp
->dtpd_mod
, "LM", 2) != 0 ||
409 !isdigit(pdp
->dtpd_mod
[2]))
412 lmid
= strtoul(&pdp
->dtpd_mod
[2], &end
, 16);
416 if (*end
!= '`' || strchr(obj
, '`') != NULL
)
423 if ((pmp
= Plmid_to_map(P
, lmid
, obj
)) == NULL
)
426 (void) Pobjname(P
, pmp
->pr_vaddr
, m
, sizeof (m
));
427 if ((obj
= strrchr(m
, '/')) == NULL
)
432 (void) Plmid(P
, pmp
->pr_vaddr
, &lmid
);
433 dt_pid_objname(pdp
->dtpd_mod
, sizeof (pdp
->dtpd_mod
), lmid
, obj
);
440 dt_pid_create_pid_probes(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
,
441 dt_pcb_t
*pcb
, dt_proc_t
*dpr
)
448 pp
.dpp_pr
= dpr
->dpr_proc
;
452 * We can only trace dynamically-linked executables (since we've
453 * hidden some magic in ld.so.1 as well as libc.so.1).
455 if (Pname_to_map(pp
.dpp_pr
, PR_OBJ_LDSO
) == NULL
) {
456 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_DYN
,
457 "process %s is not a dynamically-linked executable",
458 &pdp
->dtpd_provider
[3]));
461 pp
.dpp_mod
= pdp
->dtpd_mod
[0] != '\0' ? pdp
->dtpd_mod
: "*";
462 pp
.dpp_func
= pdp
->dtpd_func
[0] != '\0' ? pdp
->dtpd_func
: "*";
463 pp
.dpp_name
= pdp
->dtpd_name
[0] != '\0' ? pdp
->dtpd_name
: "*";
464 pp
.dpp_last_taken
= 0;
466 if (strcmp(pp
.dpp_func
, "-") == 0) {
467 const prmap_t
*aout
, *pmp
;
469 if (pdp
->dtpd_mod
[0] == '\0') {
470 pp
.dpp_mod
= pdp
->dtpd_mod
;
471 (void) strcpy(pdp
->dtpd_mod
, "a.out");
472 } else if (strisglob(pp
.dpp_mod
) ||
473 (aout
= Pname_to_map(pp
.dpp_pr
, "a.out")) == NULL
||
474 (pmp
= Pname_to_map(pp
.dpp_pr
, pp
.dpp_mod
)) == NULL
||
475 aout
->pr_vaddr
!= pmp
->pr_vaddr
) {
476 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_LIB
,
477 "only the a.out module is valid with the "
481 if (strisglob(pp
.dpp_name
)) {
482 return (dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_NAME
,
483 "only individual addresses may be specified "
484 "with the '-' function"));
489 * If pp.dpp_mod contains any globbing meta-characters, we need
490 * to iterate over each module and compare its name against the
491 * pattern. An empty module name is treated as '*'.
493 if (strisglob(pp
.dpp_mod
)) {
494 ret
= Pobject_iter(pp
.dpp_pr
, dt_pid_mod_filt
, &pp
);
500 * If we can't find a matching module, don't sweat it -- either
501 * we'll fail the enabling because the probes don't exist or
502 * we'll wait for that module to come along.
504 if ((pmp
= dt_pid_fix_mod(pdp
, pp
.dpp_pr
)) != NULL
) {
505 if ((obj
= strchr(pdp
->dtpd_mod
, '`')) == NULL
)
510 ret
= dt_pid_per_mod(&pp
, pmp
, obj
);
518 dt_pid_usdt_mapping(void *data
, const prmap_t
*pmp
, const char *oname
)
520 struct ps_prochandle
*P
= data
;
526 const char *syms
[] = { "___SUNW_dof", "__SUNW_dof" };
530 * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and
531 * __SUNW_dof is for actively-loaded DOF sections. We try to force
532 * in both types of DOF section since the process may not yet have
533 * run the code to instantiate these providers.
535 for (i
= 0; i
< 2; i
++) {
536 if (Pxlookup_by_name(P
, PR_LMID_EVERY
, oname
, syms
[i
], &sym
,
541 if ((mname
= strrchr(oname
, '/')) == NULL
)
546 dt_dprintf("lookup of %s succeeded for %s\n", syms
[i
], mname
);
548 if (Pread(P
, &e_type
, sizeof (e_type
), pmp
->pr_vaddr
+
549 offsetof(Elf64_Ehdr
, e_type
)) != sizeof (e_type
)) {
550 dt_dprintf("read of ELF header failed");
554 dh
.dofhp_dof
= sym
.st_value
;
555 dh
.dofhp_addr
= (e_type
== ET_EXEC
) ? 0 : pmp
->pr_vaddr
;
557 dt_pid_objname(dh
.dofhp_mod
, sizeof (dh
.dofhp_mod
),
558 sip
.prs_lmid
, mname
);
561 (fd
= pr_open(P
, "/dev/dtrace/helper", O_RDWR
, 0)) < 0) {
562 dt_dprintf("pr_open of helper device failed: %s\n",
564 return (-1); /* errno is set for us */
567 if (pr_ioctl(P
, fd
, DTRACEHIOC_ADDDOF
, &dh
, sizeof (dh
)) < 0)
568 dt_dprintf("DOF was rejected for %s\n", dh
.dofhp_mod
);
572 (void) pr_close(P
, fd
);
578 dt_pid_create_usdt_probes(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
,
579 dt_pcb_t
*pcb
, dt_proc_t
*dpr
)
581 struct ps_prochandle
*P
= dpr
->dpr_proc
;
584 assert(MUTEX_HELD(&dpr
->dpr_lock
));
586 (void) Pupdate_maps(P
);
587 if (Pobject_iter(P
, dt_pid_usdt_mapping
, P
) != 0) {
589 (void) dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_USDT
,
590 "failed to instantiate probes for pid %d: %s",
591 (int)Pstatus(P
)->pr_pid
, strerror(errno
));
595 * Put the module name in its canonical form.
597 (void) dt_pid_fix_mod(pdp
, P
);
603 dt_pid_get_pid(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
, dt_pcb_t
*pcb
,
607 char *c
, *last
= NULL
, *end
;
609 for (c
= &pdp
->dtpd_provider
[0]; *c
!= '\0'; c
++) {
614 if (last
== NULL
|| (*(++last
) == '\0')) {
615 (void) dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_BADPROV
,
616 "'%s' is not a valid provider", pdp
->dtpd_provider
);
621 pid
= strtol(last
, &end
, 10);
623 if (errno
!= 0 || end
== last
|| end
[0] != '\0' || pid
<= 0) {
624 (void) dt_pid_error(dtp
, pcb
, dpr
, NULL
, D_PROC_BADPID
,
625 "'%s' does not contain a valid pid", pdp
->dtpd_provider
);
633 dt_pid_create_probes(dtrace_probedesc_t
*pdp
, dtrace_hdl_t
*dtp
, dt_pcb_t
*pcb
)
635 char provname
[DTRACE_PROVNAMELEN
];
636 struct ps_prochandle
*P
;
643 if ((pid
= dt_pid_get_pid(pdp
, dtp
, pcb
, NULL
)) == -1)
646 if (dtp
->dt_ftfd
== -1) {
647 if (dtp
->dt_fterr
== ENOENT
) {
648 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_NODEV
,
649 "pid provider is not installed on this system");
651 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_NODEV
,
652 "pid provider is not available: %s",
653 strerror(dtp
->dt_fterr
));
659 (void) snprintf(provname
, sizeof (provname
), "pid%d", (int)pid
);
661 if (gmatch(provname
, pdp
->dtpd_provider
) != 0) {
662 if ((P
= dt_proc_grab(dtp
, pid
, PGRAB_RDONLY
| PGRAB_FORCE
,
664 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_GRAB
,
665 "failed to grab process %d", (int)pid
);
669 dpr
= dt_proc_lookup(dtp
, P
, 0);
671 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
673 if ((err
= dt_pid_create_pid_probes(pdp
, dtp
, pcb
, dpr
)) == 0) {
675 * Alert other retained enablings which may match
676 * against the newly created probes.
678 (void) dt_ioctl(dtp
, DTRACEIOC_ENABLE
, NULL
);
681 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
682 dt_proc_release(dtp
, P
);
686 * If it's not strictly a pid provider, we might match a USDT provider.
688 if (strcmp(provname
, pdp
->dtpd_provider
) != 0) {
689 if ((P
= dt_proc_grab(dtp
, pid
, 0, 1)) == NULL
) {
690 (void) dt_pid_error(dtp
, pcb
, NULL
, NULL
, D_PROC_GRAB
,
691 "failed to grab process %d", (int)pid
);
695 dpr
= dt_proc_lookup(dtp
, P
, 0);
697 (void) pthread_mutex_lock(&dpr
->dpr_lock
);
699 if (!dpr
->dpr_usdt
) {
700 err
= dt_pid_create_usdt_probes(pdp
, dtp
, pcb
, dpr
);
701 dpr
->dpr_usdt
= B_TRUE
;
704 (void) pthread_mutex_unlock(&dpr
->dpr_lock
);
705 dt_proc_release(dtp
, P
);
708 return (err
? -1 : 0);
712 dt_pid_create_probes_module(dtrace_hdl_t
*dtp
, dt_proc_t
*dpr
)
716 dtrace_probedesc_t
*pdp
, pd
;
718 int ret
= 0, found
= B_FALSE
;
719 char provname
[DTRACE_PROVNAMELEN
];
721 (void) snprintf(provname
, sizeof (provname
), "pid%d",
724 for (pgp
= dt_list_next(&dtp
->dt_programs
); pgp
!= NULL
;
725 pgp
= dt_list_next(pgp
)) {
727 for (stp
= dt_list_next(&pgp
->dp_stmts
); stp
!= NULL
;
728 stp
= dt_list_next(stp
)) {
730 pdp
= &stp
->ds_desc
->dtsd_ecbdesc
->dted_probe
;
731 pid
= dt_pid_get_pid(pdp
, dtp
, NULL
, dpr
);
732 if (pid
!= dpr
->dpr_pid
)
739 if (gmatch(provname
, pdp
->dtpd_provider
) != 0 &&
740 dt_pid_create_pid_probes(&pd
, dtp
, NULL
, dpr
) != 0)
744 * If it's not strictly a pid provider, we might match
747 if (strcmp(provname
, pdp
->dtpd_provider
) != 0 &&
748 dt_pid_create_usdt_probes(&pd
, dtp
, NULL
, dpr
) != 0)
755 * Give DTrace a shot to the ribs to get it to check
756 * out the newly created probes.
758 (void) dt_ioctl(dtp
, DTRACEIOC_ENABLE
, NULL
);
765 * libdtrace has a backroom deal with us to ask us for type information on
766 * behalf of pid provider probes when fasttrap doesn't return any type
767 * information. Instead we'll look up the module and see if there is type
768 * information available. However, if there is no type information available due
769 * to a lack of CTF data, then we want to make sure that DTrace still carries on
770 * in face of that. As such we don't have a meaningful exit code about failure.
771 * We emit information about why we failed to the dtrace debug log so someone
772 * can figure it out by asking nicely for DTRACE_DEBUG.
775 dt_pid_get_types(dtrace_hdl_t
*dtp
, const dtrace_probedesc_t
*pdp
,
776 dtrace_argdesc_t
*adp
, int *nargs
)
784 struct ps_prochandle
*p
;
786 char buf
[DTRACE_ARGTYPELEN
];
790 int argc
= sizeof (argv
) / sizeof (ctf_id_t
);
793 /* Set up a potential outcome */
798 * If we don't have an entry or return probe then we can just stop right
799 * now as we don't have arguments for offset probes.
801 if (strcmp(pdp
->dtpd_name
, "entry") != 0 &&
802 strcmp(pdp
->dtpd_name
, "return") != 0)
805 dmp
= dt_module_create(dtp
, pdp
->dtpd_provider
);
807 dt_dprintf("failed to find module for %s\n",
811 if (dt_module_load(dtp
, dmp
) != 0) {
812 dt_dprintf("failed to load module for %s\n",
818 * We may be working with a module that doesn't have ctf. If that's the
819 * case then we just return now and move on with life.
821 fp
= dt_module_getctflib(dtp
, dmp
, pdp
->dtpd_mod
);
823 dt_dprintf("no ctf container for %s\n",
827 p
= dt_proc_grab(dtp
, dmp
->dm_pid
, 0, PGRAB_RDONLY
| PGRAB_FORCE
);
829 dt_dprintf("failed to grab pid\n");
832 dt_proc_lock(dtp
, p
);
835 * Check to see if the D module has a link map ID and separate that out
836 * for properly interrogating libproc.
838 if ((mptr
= strchr(pdp
->dtpd_mod
, '`')) != NULL
) {
839 if (strlen(pdp
->dtpd_mod
) < 3) {
840 dt_dprintf("found weird modname with linkmap, "
841 "aborting: %s\n", pdp
->dtpd_mod
);
844 if (pdp
->dtpd_mod
[0] != 'L' || pdp
->dtpd_mod
[1] != 'M') {
845 dt_dprintf("missing leading 'LM', "
846 "aborting: %s\n", pdp
->dtpd_mod
);
850 lmid
= strtol(pdp
->dtpd_mod
+ 2, &eptr
, 16);
851 if (errno
== ERANGE
|| eptr
!= mptr
) {
852 dt_dprintf("failed to parse out lmid, aborting: %s\n",
858 mptr
= pdp
->dtpd_mod
;
862 if (Pxlookup_by_name(p
, lmid
, mptr
, pdp
->dtpd_func
,
864 dt_dprintf("failed to find function %s in %s`%s\n",
865 pdp
->dtpd_func
, pdp
->dtpd_provider
, pdp
->dtpd_mod
);
868 if (ctf_func_info(fp
, si
.prs_id
, &f
) == CTF_ERR
) {
869 dt_dprintf("failed to get ctf information for %s in %s`%s\n",
870 pdp
->dtpd_func
, pdp
->dtpd_provider
, pdp
->dtpd_mod
);
874 (void) snprintf(buf
, sizeof (buf
), "%s`%s", pdp
->dtpd_provider
,
877 if (strcmp(pdp
->dtpd_name
, "return") == 0) {
881 bzero(adp
, sizeof (dtrace_argdesc_t
));
883 adp
->dtargd_id
= pdp
->dtpd_id
;
884 adp
->dtargd_mapping
= adp
->dtargd_ndx
;
886 * We explicitly leave out the library here, we only care that
887 * it is some int. We are assuming that there is no ctf
888 * container in here that is lying about what an int is.
890 (void) snprintf(adp
->dtargd_native
, DTRACE_ARGTYPELEN
,
891 "user %s`%s", pdp
->dtpd_provider
, "int");
893 bzero(adp
, sizeof (dtrace_argdesc_t
));
895 adp
->dtargd_id
= pdp
->dtpd_id
;
896 adp
->dtargd_mapping
= adp
->dtargd_ndx
;
897 ret
= snprintf(adp
->dtargd_native
, DTRACE_ARGTYPELEN
,
899 (void) ctf_type_qname(fp
, f
.ctc_return
, adp
->dtargd_native
+
900 ret
, DTRACE_ARGTYPELEN
- ret
, buf
);
903 if (ctf_func_args(fp
, si
.prs_id
, argc
, argv
) == CTF_ERR
)
906 *nargs
= MIN(args
, f
.ctc_argc
);
907 for (i
= 0; i
< *nargs
; i
++, adp
++) {
908 bzero(adp
, sizeof (dtrace_argdesc_t
));
910 adp
->dtargd_id
= pdp
->dtpd_id
;
911 adp
->dtargd_mapping
= adp
->dtargd_ndx
;
912 ret
= snprintf(adp
->dtargd_native
, DTRACE_ARGTYPELEN
,
914 (void) ctf_type_qname(fp
, argv
[i
], adp
->dtargd_native
+
915 ret
, DTRACE_ARGTYPELEN
- ret
, buf
);
919 dt_proc_unlock(dtp
, p
);
920 dt_proc_release(dtp
, p
);