Deleted Added
full compact
systrace.c (179237) systrace.c (184698)
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

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]
18 *
19 * CDDL HEADER END
20 *
21 * Portions Copyright 2006-2008 John Birrell jb@freebsd.org
22 *
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

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]
18 *
19 * CDDL HEADER END
20 *
21 * Portions Copyright 2006-2008 John Birrell jb@freebsd.org
22 *
23 * $FreeBSD: head/sys/cddl/dev/systrace/systrace.c 179237 2008-05-23 05:59:42Z jb $
23 * $FreeBSD: head/sys/cddl/dev/systrace/systrace.c 184698 2008-11-05 19:39:11Z rodrigc $
24 *
25 */
26
27/*
28 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31

--- 13 unchanged lines hidden (view full) ---

45#include <sys/lock.h>
46#include <sys/malloc.h>
47#include <sys/module.h>
48#include <sys/mutex.h>
49#include <sys/poll.h>
50#include <sys/proc.h>
51#include <sys/selinfo.h>
52#include <sys/smp.h>
24 *
25 */
26
27/*
28 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31

--- 13 unchanged lines hidden (view full) ---

45#include <sys/lock.h>
46#include <sys/malloc.h>
47#include <sys/module.h>
48#include <sys/mutex.h>
49#include <sys/poll.h>
50#include <sys/proc.h>
51#include <sys/selinfo.h>
52#include <sys/smp.h>
53#include <sys/syscall.h>
54#include <sys/sysent.h>
55#include <sys/sysproto.h>
53#include <sys/sysproto.h>
54#include <sys/sysent.h>
56#include <sys/uio.h>
57#include <sys/unistd.h>
58#include <machine/stdarg.h>
59
60#include <sys/dtrace.h>
61
55#include <sys/uio.h>
56#include <sys/unistd.h>
57#include <machine/stdarg.h>
58
59#include <sys/dtrace.h>
60
61#ifdef LINUX_SYSTRACE
62#include <linux.h>
63#include <linux_syscall.h>
64#include <linux_proto.h>
65#include <linux_syscallnames.c>
66#include <linux_systrace.c>
67extern struct sysent linux_sysent[];
68#define DEVNAME "dtrace/linsystrace"
69#define PROVNAME "linsyscall"
70#define MAXSYSCALL LINUX_SYS_MAXSYSCALL
71#define SYSCALLNAMES linux_syscallnames
72#define SYSENT linux_sysent
73#else
74/*
75 * The syscall arguments are processed into a DTrace argument array
76 * using a generated function. See sys/kern/makesyscalls.sh.
77 */
78#include <sys/syscall.h>
79#include <kern/systrace_args.c>
80extern const char *syscallnames[];
81#define DEVNAME "dtrace/systrace"
82#define PROVNAME "syscall"
83#define MAXSYSCALL SYS_MAXSYSCALL
84#define SYSCALLNAMES syscallnames
85#define SYSENT sysent
86#endif
87
62#define SYSTRACE_ARTIFICIAL_FRAMES 1
63
64#define SYSTRACE_SHIFT 16
65#define SYSTRACE_ISENTRY(x) ((int)(x) >> SYSTRACE_SHIFT)
66#define SYSTRACE_SYSNUM(x) ((int)(x) & ((1 << SYSTRACE_SHIFT) - 1))
67#define SYSTRACE_ENTRY(id) ((1 << SYSTRACE_SHIFT) | (id))
68#define SYSTRACE_RETURN(id) (id)
69
88#define SYSTRACE_ARTIFICIAL_FRAMES 1
89
90#define SYSTRACE_SHIFT 16
91#define SYSTRACE_ISENTRY(x) ((int)(x) >> SYSTRACE_SHIFT)
92#define SYSTRACE_SYSNUM(x) ((int)(x) & ((1 << SYSTRACE_SHIFT) - 1))
93#define SYSTRACE_ENTRY(id) ((1 << SYSTRACE_SHIFT) | (id))
94#define SYSTRACE_RETURN(id) (id)
95
70#if ((1 << SYSTRACE_SHIFT) <= SYS_MAXSYSCALL)
96#if ((1 << SYSTRACE_SHIFT) <= MAXSYSCALL)
71#error 1 << SYSTRACE_SHIFT must exceed number of system calls
72#endif
73
97#error 1 << SYSTRACE_SHIFT must exceed number of system calls
98#endif
99
74extern char *syscallnames[];
75
76static d_open_t systrace_open;
77static int systrace_unload(void);
78static void systrace_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
100static d_open_t systrace_open;
101static int systrace_unload(void);
102static void systrace_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
79static void systrace_args(int, void *, u_int64_t *, int *);
80static void systrace_probe(u_int32_t, int, struct sysent *, void *);
81static void systrace_provide(void *, dtrace_probedesc_t *);
82static void systrace_destroy(void *, dtrace_id_t, void *);
83static void systrace_enable(void *, dtrace_id_t, void *);
84static void systrace_disable(void *, dtrace_id_t, void *);
85static void systrace_load(void *);
86
87static struct cdevsw systrace_cdevsw = {
88 .d_version = D_VERSION,
89 .d_open = systrace_open,
103static void systrace_provide(void *, dtrace_probedesc_t *);
104static void systrace_destroy(void *, dtrace_id_t, void *);
105static void systrace_enable(void *, dtrace_id_t, void *);
106static void systrace_disable(void *, dtrace_id_t, void *);
107static void systrace_load(void *);
108
109static struct cdevsw systrace_cdevsw = {
110 .d_version = D_VERSION,
111 .d_open = systrace_open,
112#ifdef LINUX_SYSTRACE
113 .d_name = "linsystrace",
114#else
90 .d_name = "systrace",
115 .d_name = "systrace",
116#endif
91};
92
117};
118
119static union {
120 const char **p_constnames;
121 char **pp_syscallnames;
122} uglyhack = { SYSCALLNAMES };
123
93static dtrace_pattr_t systrace_attr = {
94{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
95{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
96{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
97{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
98{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
99};
100

--- 8 unchanged lines hidden (view full) ---

109 NULL,
110 NULL,
111 systrace_destroy
112};
113
114static struct cdev *systrace_cdev;
115static dtrace_provider_id_t systrace_id;
116
124static dtrace_pattr_t systrace_attr = {
125{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
126{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
127{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
128{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
129{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
130};
131

--- 8 unchanged lines hidden (view full) ---

140 NULL,
141 NULL,
142 systrace_destroy
143};
144
145static struct cdev *systrace_cdev;
146static dtrace_provider_id_t systrace_id;
147
148#if !defined(LINUX_SYSTRACE)
117/*
149/*
118 * The syscall arguments are processed into a DTrace argument array
119 * using a generated function. See sys/kern/makesyscalls.sh.
150 * Probe callback function.
151 *
152 * Note: This function is called for _all_ syscalls, regardless of which sysent
153 * array the syscall comes from. It could be a standard syscall or a
154 * compat syscall from something like Linux.
120 */
155 */
121#include <kern/systrace_args.c>
122
123static void
124systrace_probe(u_int32_t id, int sysnum, struct sysent *sysent, void *params)
125{
126 int n_args = 0;
127 u_int64_t uargs[8];
128
129 /*
156static void
157systrace_probe(u_int32_t id, int sysnum, struct sysent *sysent, void *params)
158{
159 int n_args = 0;
160 u_int64_t uargs[8];
161
162 /*
130 * Check if this syscall has a custom argument conversion
131 * function registered. If so, it is a syscall registered
132 * by a loaded module.
163 * Check if this syscall has an argument conversion function
164 * registered.
133 */
134 if (sysent->sy_systrace_args_func != NULL)
135 /*
136 * Convert the syscall parameters using the registered
137 * function.
138 */
165 */
166 if (sysent->sy_systrace_args_func != NULL)
167 /*
168 * Convert the syscall parameters using the registered
169 * function.
170 */
139 (*sysent->sy_systrace_args_func)(params, uargs, &n_args);
171 (*sysent->sy_systrace_args_func)(sysnum, params, uargs, &n_args);
140 else
141 /*
142 * Use the built-in system call argument conversion
143 * function to translate the syscall structure fields
172 else
173 /*
174 * Use the built-in system call argument conversion
175 * function to translate the syscall structure fields
144 * into thhe array of 64-bit values that DTrace
176 * into the array of 64-bit values that DTrace
145 * expects.
146 */
147 systrace_args(sysnum, params, uargs, &n_args);
148
149 /* Process the probe using the converted argments. */
150 dtrace_probe(id, uargs[0], uargs[1], uargs[2], uargs[3], uargs[4]);
151}
177 * expects.
178 */
179 systrace_args(sysnum, params, uargs, &n_args);
180
181 /* Process the probe using the converted argments. */
182 dtrace_probe(id, uargs[0], uargs[1], uargs[2], uargs[3], uargs[4]);
183}
184#endif
152
153static void
154systrace_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
155{
156 int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
157
158 systrace_setargdesc(sysnum, desc->dtargd_ndx, desc->dtargd_native,
159 sizeof(desc->dtargd_native));

--- 7 unchanged lines hidden (view full) ---

167static void
168systrace_provide(void *arg, dtrace_probedesc_t *desc)
169{
170 int i;
171
172 if (desc != NULL)
173 return;
174
185
186static void
187systrace_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
188{
189 int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
190
191 systrace_setargdesc(sysnum, desc->dtargd_ndx, desc->dtargd_native,
192 sizeof(desc->dtargd_native));

--- 7 unchanged lines hidden (view full) ---

200static void
201systrace_provide(void *arg, dtrace_probedesc_t *desc)
202{
203 int i;
204
205 if (desc != NULL)
206 return;
207
175 for (i = 0; i < SYS_MAXSYSCALL; i++) {
208 for (i = 0; i < MAXSYSCALL; i++) {
176 if (dtrace_probe_lookup(systrace_id, NULL,
209 if (dtrace_probe_lookup(systrace_id, NULL,
177 syscallnames[i], "entry") != 0)
210 uglyhack.pp_syscallnames[i], "entry") != 0)
178 continue;
179
211 continue;
212
180 (void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],
213 (void) dtrace_probe_create(systrace_id, NULL, uglyhack.pp_syscallnames[i],
181 "entry", SYSTRACE_ARTIFICIAL_FRAMES,
182 (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
214 "entry", SYSTRACE_ARTIFICIAL_FRAMES,
215 (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
183 (void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],
216 (void) dtrace_probe_create(systrace_id, NULL, uglyhack.pp_syscallnames[i],
184 "return", SYSTRACE_ARTIFICIAL_FRAMES,
185 (void *)((uintptr_t)SYSTRACE_RETURN(i)));
186 }
187}
188
189static void
190systrace_destroy(void *arg, dtrace_id_t id, void *parg)
191{

--- 12 unchanged lines hidden (view full) ---

204#endif
205}
206
207static void
208systrace_enable(void *arg, dtrace_id_t id, void *parg)
209{
210 int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
211
217 "return", SYSTRACE_ARTIFICIAL_FRAMES,
218 (void *)((uintptr_t)SYSTRACE_RETURN(i)));
219 }
220}
221
222static void
223systrace_destroy(void *arg, dtrace_id_t id, void *parg)
224{

--- 12 unchanged lines hidden (view full) ---

237#endif
238}
239
240static void
241systrace_enable(void *arg, dtrace_id_t id, void *parg)
242{
243 int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
244
245 if (SYSENT[sysnum].sy_systrace_args_func == NULL)
246 SYSENT[sysnum].sy_systrace_args_func = systrace_args;
247
212 if (SYSTRACE_ISENTRY((uintptr_t)parg))
248 if (SYSTRACE_ISENTRY((uintptr_t)parg))
213 sysent[sysnum].sy_entry = id;
249 SYSENT[sysnum].sy_entry = id;
214 else
250 else
215 sysent[sysnum].sy_return = id;
251 SYSENT[sysnum].sy_return = id;
216}
217
218static void
219systrace_disable(void *arg, dtrace_id_t id, void *parg)
220{
221 int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
222
252}
253
254static void
255systrace_disable(void *arg, dtrace_id_t id, void *parg)
256{
257 int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
258
223 sysent[sysnum].sy_entry = 0;
224 sysent[sysnum].sy_return = 0;
259 SYSENT[sysnum].sy_entry = 0;
260 SYSENT[sysnum].sy_return = 0;
225}
226
227static void
228systrace_load(void *dummy)
229{
230 /* Create the /dev/dtrace/systrace entry. */
231 systrace_cdev = make_dev(&systrace_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
261}
262
263static void
264systrace_load(void *dummy)
265{
266 /* Create the /dev/dtrace/systrace entry. */
267 systrace_cdev = make_dev(&systrace_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
232 "dtrace/systrace");
268 DEVNAME);
233
269
234 if (dtrace_register("syscall", &systrace_attr, DTRACE_PRIV_USER,
270 if (dtrace_register(PROVNAME, &systrace_attr, DTRACE_PRIV_USER,
235 NULL, &systrace_pops, NULL, &systrace_id) != 0)
236 return;
237
271 NULL, &systrace_pops, NULL, &systrace_id) != 0)
272 return;
273
274#if !defined(LINUX_SYSTRACE)
238 systrace_probe_func = systrace_probe;
275 systrace_probe_func = systrace_probe;
276#endif
239}
240
241
242static int
243systrace_unload()
244{
245 int error = 0;
246
247 if ((error = dtrace_unregister(systrace_id)) != 0)
248 return (error);
249
277}
278
279
280static int
281systrace_unload()
282{
283 int error = 0;
284
285 if ((error = dtrace_unregister(systrace_id)) != 0)
286 return (error);
287
288#if !defined(LINUX_SYSTRACE)
250 systrace_probe_func = NULL;
289 systrace_probe_func = NULL;
290#endif
251
252 destroy_dev(systrace_cdev);
253
254 return (error);
255}
256
257static int
258systrace_modevent(module_t mod __unused, int type, void *data __unused)

--- 22 unchanged lines hidden (view full) ---

281systrace_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused)
282{
283 return (0);
284}
285
286SYSINIT(systrace_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, systrace_load, NULL);
287SYSUNINIT(systrace_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, systrace_unload, NULL);
288
291
292 destroy_dev(systrace_cdev);
293
294 return (error);
295}
296
297static int
298systrace_modevent(module_t mod __unused, int type, void *data __unused)

--- 22 unchanged lines hidden (view full) ---

321systrace_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused)
322{
323 return (0);
324}
325
326SYSINIT(systrace_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, systrace_load, NULL);
327SYSUNINIT(systrace_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, systrace_unload, NULL);
328
329#ifdef LINUX_SYSTRACE
330DEV_MODULE(linsystrace, systrace_modevent, NULL);
331MODULE_VERSION(linsystrace, 1);
332MODULE_DEPEND(linsystrace, linux, 1, 1, 1);
333MODULE_DEPEND(linsystrace, systrace, 1, 1, 1);
334MODULE_DEPEND(linsystrace, dtrace, 1, 1, 1);
335MODULE_DEPEND(linsystrace, opensolaris, 1, 1, 1);
336#else
289DEV_MODULE(systrace, systrace_modevent, NULL);
290MODULE_VERSION(systrace, 1);
291MODULE_DEPEND(systrace, dtrace, 1, 1, 1);
292MODULE_DEPEND(systrace, opensolaris, 1, 1, 1);
337DEV_MODULE(systrace, systrace_modevent, NULL);
338MODULE_VERSION(systrace, 1);
339MODULE_DEPEND(systrace, dtrace, 1, 1, 1);
340MODULE_DEPEND(systrace, opensolaris, 1, 1, 1);
341#endif