1*fed1ca4bSRuslan Bukin /*
2*fed1ca4bSRuslan Bukin * CDDL HEADER START
3*fed1ca4bSRuslan Bukin *
4*fed1ca4bSRuslan Bukin * The contents of this file are subject to the terms of the
5*fed1ca4bSRuslan Bukin * Common Development and Distribution License, Version 1.0 only
6*fed1ca4bSRuslan Bukin * (the "License"). You may not use this file except in compliance
7*fed1ca4bSRuslan Bukin * with the License.
8*fed1ca4bSRuslan Bukin *
9*fed1ca4bSRuslan Bukin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*fed1ca4bSRuslan Bukin * or http://www.opensolaris.org/os/licensing.
11*fed1ca4bSRuslan Bukin * See the License for the specific language governing permissions
12*fed1ca4bSRuslan Bukin * and limitations under the License.
13*fed1ca4bSRuslan Bukin *
14*fed1ca4bSRuslan Bukin * When distributing Covered Code, include this CDDL HEADER in each
15*fed1ca4bSRuslan Bukin * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*fed1ca4bSRuslan Bukin * If applicable, add the following below this CDDL HEADER, with the
17*fed1ca4bSRuslan Bukin * fields enclosed by brackets "[]" replaced with your own identifying
18*fed1ca4bSRuslan Bukin * information: Portions Copyright [yyyy] [name of copyright owner]
19*fed1ca4bSRuslan Bukin *
20*fed1ca4bSRuslan Bukin * CDDL HEADER END
21*fed1ca4bSRuslan Bukin */
22*fed1ca4bSRuslan Bukin /*
23*fed1ca4bSRuslan Bukin * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*fed1ca4bSRuslan Bukin * Use is subject to license terms.
25*fed1ca4bSRuslan Bukin * Copyright 2014 Howard Su
26*fed1ca4bSRuslan Bukin * Copyright 2015 George V. Neville-Neil
27*fed1ca4bSRuslan Bukin * Copyright 2015 Ruslan Bukin <br@bsdpad.com>
28*fed1ca4bSRuslan Bukin */
29*fed1ca4bSRuslan Bukin
30*fed1ca4bSRuslan Bukin #pragma ident "%Z%%M% %I% %E% SMI"
31*fed1ca4bSRuslan Bukin
32*fed1ca4bSRuslan Bukin #include <stdlib.h>
33*fed1ca4bSRuslan Bukin #include <assert.h>
34*fed1ca4bSRuslan Bukin #include <errno.h>
35*fed1ca4bSRuslan Bukin #include <string.h>
36*fed1ca4bSRuslan Bukin #include <libgen.h>
37*fed1ca4bSRuslan Bukin
38*fed1ca4bSRuslan Bukin #include <dt_impl.h>
39*fed1ca4bSRuslan Bukin #include <dt_pid.h>
40*fed1ca4bSRuslan Bukin
41*fed1ca4bSRuslan Bukin #if !defined(sun)
42*fed1ca4bSRuslan Bukin #include <libproc_compat.h>
43*fed1ca4bSRuslan Bukin #endif
44*fed1ca4bSRuslan Bukin
45*fed1ca4bSRuslan Bukin /*ARGSUSED*/
46*fed1ca4bSRuslan Bukin int
dt_pid_create_entry_probe(struct ps_prochandle * P,dtrace_hdl_t * dtp,fasttrap_probe_spec_t * ftp,const GElf_Sym * symp)47*fed1ca4bSRuslan Bukin dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
48*fed1ca4bSRuslan Bukin fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
49*fed1ca4bSRuslan Bukin {
50*fed1ca4bSRuslan Bukin
51*fed1ca4bSRuslan Bukin ftp->ftps_type = DTFTP_ENTRY;
52*fed1ca4bSRuslan Bukin ftp->ftps_pc = (uintptr_t)symp->st_value;
53*fed1ca4bSRuslan Bukin ftp->ftps_size = (size_t)symp->st_size;
54*fed1ca4bSRuslan Bukin ftp->ftps_noffs = 1;
55*fed1ca4bSRuslan Bukin ftp->ftps_offs[0] = 0;
56*fed1ca4bSRuslan Bukin
57*fed1ca4bSRuslan Bukin if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
58*fed1ca4bSRuslan Bukin dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
59*fed1ca4bSRuslan Bukin strerror(errno));
60*fed1ca4bSRuslan Bukin return (dt_set_errno(dtp, errno));
61*fed1ca4bSRuslan Bukin }
62*fed1ca4bSRuslan Bukin
63*fed1ca4bSRuslan Bukin return (1);
64*fed1ca4bSRuslan Bukin }
65*fed1ca4bSRuslan Bukin
66*fed1ca4bSRuslan Bukin int
dt_pid_create_return_probe(struct ps_prochandle * P,dtrace_hdl_t * dtp,fasttrap_probe_spec_t * ftp,const GElf_Sym * symp,uint64_t * stret)67*fed1ca4bSRuslan Bukin dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
68*fed1ca4bSRuslan Bukin fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
69*fed1ca4bSRuslan Bukin {
70*fed1ca4bSRuslan Bukin
71*fed1ca4bSRuslan Bukin dt_dprintf("%s: unimplemented\n", __func__);
72*fed1ca4bSRuslan Bukin
73*fed1ca4bSRuslan Bukin return (DT_PROC_ERR);
74*fed1ca4bSRuslan Bukin }
75*fed1ca4bSRuslan Bukin
76*fed1ca4bSRuslan Bukin /*ARGSUSED*/
77*fed1ca4bSRuslan Bukin int
dt_pid_create_offset_probe(struct ps_prochandle * P,dtrace_hdl_t * dtp,fasttrap_probe_spec_t * ftp,const GElf_Sym * symp,ulong_t off)78*fed1ca4bSRuslan Bukin dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
79*fed1ca4bSRuslan Bukin fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
80*fed1ca4bSRuslan Bukin {
81*fed1ca4bSRuslan Bukin
82*fed1ca4bSRuslan Bukin if (!ALIGNED_POINTER(off, 4))
83*fed1ca4bSRuslan Bukin return (DT_PROC_ALIGN);
84*fed1ca4bSRuslan Bukin
85*fed1ca4bSRuslan Bukin ftp->ftps_type = DTFTP_OFFSETS;
86*fed1ca4bSRuslan Bukin ftp->ftps_pc = (uintptr_t)symp->st_value;
87*fed1ca4bSRuslan Bukin ftp->ftps_size = (size_t)symp->st_size;
88*fed1ca4bSRuslan Bukin ftp->ftps_noffs = 1;
89*fed1ca4bSRuslan Bukin ftp->ftps_offs[0] = off;
90*fed1ca4bSRuslan Bukin
91*fed1ca4bSRuslan Bukin if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
92*fed1ca4bSRuslan Bukin dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
93*fed1ca4bSRuslan Bukin strerror(errno));
94*fed1ca4bSRuslan Bukin return (dt_set_errno(dtp, errno));
95*fed1ca4bSRuslan Bukin }
96*fed1ca4bSRuslan Bukin
97*fed1ca4bSRuslan Bukin return (1);
98*fed1ca4bSRuslan Bukin }
99*fed1ca4bSRuslan Bukin
100*fed1ca4bSRuslan Bukin /*ARGSUSED*/
101*fed1ca4bSRuslan Bukin int
dt_pid_create_glob_offset_probes(struct ps_prochandle * P,dtrace_hdl_t * dtp,fasttrap_probe_spec_t * ftp,const GElf_Sym * symp,const char * pattern)102*fed1ca4bSRuslan Bukin dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
103*fed1ca4bSRuslan Bukin fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
104*fed1ca4bSRuslan Bukin {
105*fed1ca4bSRuslan Bukin ulong_t i;
106*fed1ca4bSRuslan Bukin
107*fed1ca4bSRuslan Bukin ftp->ftps_type = DTFTP_OFFSETS;
108*fed1ca4bSRuslan Bukin ftp->ftps_pc = (uintptr_t)symp->st_value;
109*fed1ca4bSRuslan Bukin ftp->ftps_size = (size_t)symp->st_size;
110*fed1ca4bSRuslan Bukin ftp->ftps_noffs = 0;
111*fed1ca4bSRuslan Bukin
112*fed1ca4bSRuslan Bukin /*
113*fed1ca4bSRuslan Bukin * If we're matching against everything, just iterate through each
114*fed1ca4bSRuslan Bukin * instruction in the function, otherwise look for matching offset
115*fed1ca4bSRuslan Bukin * names by constructing the string and comparing it against the
116*fed1ca4bSRuslan Bukin * pattern.
117*fed1ca4bSRuslan Bukin */
118*fed1ca4bSRuslan Bukin if (strcmp("*", pattern) == 0) {
119*fed1ca4bSRuslan Bukin for (i = 0; i < symp->st_size; i += 4) {
120*fed1ca4bSRuslan Bukin ftp->ftps_offs[ftp->ftps_noffs++] = i;
121*fed1ca4bSRuslan Bukin }
122*fed1ca4bSRuslan Bukin } else {
123*fed1ca4bSRuslan Bukin char name[sizeof (i) * 2 + 1];
124*fed1ca4bSRuslan Bukin
125*fed1ca4bSRuslan Bukin for (i = 0; i < symp->st_size; i += 4) {
126*fed1ca4bSRuslan Bukin (void) sprintf(name, "%lx", i);
127*fed1ca4bSRuslan Bukin if (gmatch(name, pattern))
128*fed1ca4bSRuslan Bukin ftp->ftps_offs[ftp->ftps_noffs++] = i;
129*fed1ca4bSRuslan Bukin }
130*fed1ca4bSRuslan Bukin }
131*fed1ca4bSRuslan Bukin
132*fed1ca4bSRuslan Bukin if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
133*fed1ca4bSRuslan Bukin dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
134*fed1ca4bSRuslan Bukin strerror(errno));
135*fed1ca4bSRuslan Bukin return (dt_set_errno(dtp, errno));
136*fed1ca4bSRuslan Bukin }
137*fed1ca4bSRuslan Bukin
138*fed1ca4bSRuslan Bukin return (ftp->ftps_noffs);
139*fed1ca4bSRuslan Bukin }
140