Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/cddl/contrib/opensolaris/lib/libdtrace/arm/dt_isadep.c
39563 views
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, Version 1.0 only
6
* (the "License"). You may not use this file except in compliance
7
* with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or http://www.opensolaris.org/os/licensing.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
* Copyright 2014 Howard Su
26
* Copyright 2015 George V. Neville-Neil
27
*
28
*/
29
30
#pragma ident "%Z%%M% %I% %E% SMI"
31
32
#include <stdlib.h>
33
#include <assert.h>
34
#include <errno.h>
35
#include <string.h>
36
#include <libgen.h>
37
38
#include <dt_impl.h>
39
#include <dt_pid.h>
40
41
#ifdef __FreeBSD__
42
#include <libproc_compat.h>
43
#endif
44
45
#define OP(x) ((x) >> 30)
46
#define OP2(x) (((x) >> 22) & 0x07)
47
#define COND(x) (((x) >> 25) & 0x0f)
48
#define A(x) (((x) >> 29) & 0x01)
49
50
#define OP_BRANCH 0
51
52
#define OP2_BPcc 0x1
53
#define OP2_Bicc 0x2
54
#define OP2_BPr 0x3
55
#define OP2_FBPfcc 0x5
56
#define OP2_FBfcc 0x6
57
58
/*ARGSUSED*/
59
int
60
dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
61
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
62
{
63
ftp->ftps_type = DTFTP_ENTRY;
64
ftp->ftps_pc = (uintptr_t)symp->st_value;
65
ftp->ftps_size = (size_t)symp->st_size;
66
ftp->ftps_noffs = 1;
67
ftp->ftps_offs[0] = 0;
68
69
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
70
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
71
strerror(errno));
72
return (dt_set_errno(dtp, errno));
73
}
74
75
return (1);
76
}
77
78
int
79
dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
80
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
81
{
82
83
uint32_t *text;
84
int i;
85
int srdepth = 0;
86
87
dt_dprintf("%s: unimplemented\n", __func__);
88
return (DT_PROC_ERR);
89
90
if ((text = malloc(symp->st_size + 4)) == NULL) {
91
dt_dprintf("mr sparkle: malloc() failed\n");
92
return (DT_PROC_ERR);
93
}
94
95
if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) {
96
dt_dprintf("mr sparkle: Pread() failed\n");
97
free(text);
98
return (DT_PROC_ERR);
99
}
100
101
/*
102
* Leave a dummy instruction in the last slot to simplify edge
103
* conditions.
104
*/
105
text[symp->st_size / 4] = 0;
106
107
ftp->ftps_type = DTFTP_RETURN;
108
ftp->ftps_pc = symp->st_value;
109
ftp->ftps_size = symp->st_size;
110
ftp->ftps_noffs = 0;
111
112
113
free(text);
114
if (ftp->ftps_noffs > 0) {
115
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
116
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
117
strerror(errno));
118
return (dt_set_errno(dtp, errno));
119
}
120
}
121
122
123
return (ftp->ftps_noffs);
124
}
125
126
/*ARGSUSED*/
127
int
128
dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
129
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
130
{
131
if (off & 0x3)
132
return (DT_PROC_ALIGN);
133
134
ftp->ftps_type = DTFTP_OFFSETS;
135
ftp->ftps_pc = (uintptr_t)symp->st_value;
136
ftp->ftps_size = (size_t)symp->st_size;
137
ftp->ftps_noffs = 1;
138
ftp->ftps_offs[0] = off;
139
140
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
141
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
142
strerror(errno));
143
return (dt_set_errno(dtp, errno));
144
}
145
146
return (1);
147
}
148
149
/*ARGSUSED*/
150
int
151
dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
152
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
153
{
154
ulong_t i;
155
156
ftp->ftps_type = DTFTP_OFFSETS;
157
ftp->ftps_pc = (uintptr_t)symp->st_value;
158
ftp->ftps_size = (size_t)symp->st_size;
159
ftp->ftps_noffs = 0;
160
161
/*
162
* If we're matching against everything, just iterate through each
163
* instruction in the function, otherwise look for matching offset
164
* names by constructing the string and comparing it against the
165
* pattern.
166
*/
167
if (strcmp("*", pattern) == 0) {
168
for (i = 0; i < symp->st_size; i += 4) {
169
ftp->ftps_offs[ftp->ftps_noffs++] = i;
170
}
171
} else {
172
char name[sizeof (i) * 2 + 1];
173
174
for (i = 0; i < symp->st_size; i += 4) {
175
(void) sprintf(name, "%lx", i);
176
if (gmatch(name, pattern))
177
ftp->ftps_offs[ftp->ftps_noffs++] = i;
178
}
179
}
180
181
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
182
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
183
strerror(errno));
184
return (dt_set_errno(dtp, errno));
185
}
186
187
return (ftp->ftps_noffs);
188
}
189
190