xref: /freebsd/cddl/contrib/opensolaris/lib/libdtrace/riscv/dt_isadep.c (revision fed1ca4b719c56c930f2259d80663cd34be812bb)
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