1/* $NetBSD: ktrace.h,v 1.71 2025/04/06 19:13:06 riastradh Exp $ */
2
3/*
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)ktrace.h 8.2 (Berkeley) 2/19/95
32 */
33
34#ifndef _SYS_KTRACE_H_
35#define _SYS_KTRACE_H_
36
37#include <sys/param.h>
38
39#include <sys/mutex.h>
40#include <sys/lwp.h>
41#include <sys/signal.h>
42#include <sys/time.h>
43#include <sys/uio.h>
44
45/*
46 * operations to ktrace system call (KTROP(op))
47 */
48#define KTROP_SET 0 /* set trace points */
49#define KTROP_CLEAR 1 /* clear trace points */
50#define KTROP_CLEARFILE 2 /* stop all tracing to file */
51#define KTROP_MASK 0x3
52#define KTROP(o) ((o)&KTROP_MASK) /* macro to extract operation */
53/*
54 * flags (ORed in with operation)
55 */
56#define KTRFLAG_DESCEND 4 /* perform op on all children too */
57
58/*
59 * ktrace record header
60 */
61struct ktr_header {
62 int ktr_len; /* length of record minus length of old header */
63#if BYTE_ORDER == LITTLE_ENDIAN
64 short ktr_type; /* trace record type */
65 short ktr_version; /* trace record version */
66#else
67 short ktr_version; /* trace record version */
68 short ktr_type; /* trace record type */
69#endif
70 pid_t ktr_pid; /* process id */
71 char ktr_comm[MAXCOMLEN+1]; /* command name */
72 union {
73 struct { /* v0 */
74 struct {
75 int32_t tv_sec;
76 long tv_usec;
77 } _tv;
78 const void *_buf;
79 } _v0;
80 struct { /* v1 */
81 struct {
82 int32_t tv_sec;
83 long tv_nsec;
84 } _ts;
85 lwpid_t _lid;
86 } _v1;
87 struct { /* v2 */
88 struct timespec _ts;
89 lwpid_t _lid;
90 } _v2;
91 } _v;
92};
93
94#define ktr_lid _v._v2._lid
95#define ktr_olid _v._v1._lid
96#define ktr_time _v._v2._ts
97#define ktr_otv _v._v0._tv
98#define ktr_ots _v._v1._ts
99#define ktr_ts _v._v2._ts
100#define ktr_unused _v._v0._buf
101
102#define KTR_SHIMLEN offsetof(struct ktr_header, ktr_pid)
103
104/*
105 * Test for kernel trace point
106 */
107#define KTRPOINT(p, type) \
108 (((p)->p_traceflag & (1<<(type))) != 0)
109
110/*
111 * ktrace record types
112 */
113
114/*
115 * KTR_SYSCALL - system call record
116 */
117#define KTR_SYSCALL 1
118struct ktr_syscall {
119 int ktr_code; /* syscall number */
120 int ktr_argsize; /* size of arguments */
121 /*
122 * followed by ktr_argsize/sizeof(register_t) "register_t"s
123 */
124};
125
126/*
127 * KTR_SYSRET - return from system call record
128 */
129#define KTR_SYSRET 2
130struct ktr_sysret {
131 short ktr_code;
132 short ktr_eosys; /* XXX unused */
133 int ktr_error;
134 __register_t ktr_retval;
135 __register_t ktr_retval_1;
136};
137
138/*
139 * KTR_NAMEI - namei record
140 */
141#define KTR_NAMEI 3
142 /* record contains pathname */
143
144/*
145 * KTR_GENIO - trace generic process i/o
146 */
147#define KTR_GENIO 4
148struct ktr_genio {
149 int ktr_fd;
150 enum uio_rw ktr_rw;
151 /*
152 * followed by data successfully read/written
153 */
154};
155
156/*
157 * KTR_PSIG - trace processed signal
158 */
159#define KTR_PSIG 5
160struct ktr_psig {
161 int signo;
162 sig_t action;
163 sigset_t mask;
164 int code;
165 /*
166 * followed by optional siginfo_t
167 */
168};
169
170/*
171 * KTR_CSW - trace context switches
172 */
173#define KTR_CSW 6
174struct ktr_csw {
175 int out; /* 1 if switch out, 0 if switch in */
176 int user; /* 1 if usermode (ivcsw), 0 if kernel (vcsw) */
177};
178
179/*
180 * KTR_EMUL - emulation change
181 */
182#define KTR_EMUL 7
183 /* record contains emulation name */
184
185/*
186 * KTR_USER - user record
187 */
188#define KTR_USER 8
189#define KTR_USER_MAXIDLEN 20
190#define KTR_USER_MAXLEN 2048 /* maximum length of passed data */
191struct ktr_user {
192 char ktr_id[KTR_USER_MAXIDLEN]; /* string id of caller */
193 /*
194 * Followed by ktr_len - sizeof(struct ktr_user) of user data.
195 */
196};
197
198/*
199 * KTR_EXEC_ARG, KTR_EXEC_ENV - Arguments and environment from exec
200 */
201#define KTR_EXEC_ARG 10
202#define KTR_EXEC_ENV 11
203 /* record contains arg/env string */
204
205/*
206 * KTR_SAUPCALL - scheduler activated upcall.
207 *
208 * The structure is no longer used, but retained for compatibility.
209 */
210#define KTR_SAUPCALL 13
211struct ktr_saupcall {
212 int ktr_type;
213 int ktr_nevent;
214 int ktr_nint;
215 void *ktr_sas;
216 void *ktr_ap;
217 /*
218 * followed by nevent sa_t's from sas[]
219 */
220};
221
222/*
223 * KTR_MIB - MIB name and data
224 */
225#define KTR_MIB 14
226 /* Record contains MIB name */
227
228/*
229 * KTR_EXEC_FD - Opened file descriptor from exec
230 */
231#define KTR_EXEC_FD 15
232struct ktr_execfd {
233 int ktr_fd;
234 u_int ktr_dtype; /* one of DTYPE_* constants */
235};
236
237/*
238 * kernel trace points (in p_traceflag)
239 */
240#define KTRFAC_MASK 0x00ffffff
241#define KTRFAC_SYSCALL (1<<KTR_SYSCALL)
242#define KTRFAC_SYSRET (1<<KTR_SYSRET)
243#define KTRFAC_NAMEI (1<<KTR_NAMEI)
244#define KTRFAC_GENIO (1<<KTR_GENIO)
245#define KTRFAC_PSIG (1<<KTR_PSIG)
246#define KTRFAC_CSW (1<<KTR_CSW)
247#define KTRFAC_EMUL (1<<KTR_EMUL)
248#define KTRFAC_USER (1<<KTR_USER)
249#define KTRFAC_EXEC_ARG (1<<KTR_EXEC_ARG)
250#define KTRFAC_EXEC_ENV (1<<KTR_EXEC_ENV)
251#define KTRFAC_MIB (1<<KTR_MIB)
252#define KTRFAC_EXEC_FD (1<<KTR_EXEC_FD)
253
254#define __KTRACE_FLAG_BITS \
255 "\177\020" \
256 "b\1SYSCALL\0" \
257 "b\2SYSRET\0" \
258 "b\3NAMEI\0" \
259 "b\4GENIO\0" \
260 "b\5PSIG\0" \
261 "b\6CSW\0" \
262 "b\7EMUL\0" \
263 "b\10USER\0" \
264 "b\12EXEC_ARG\0" \
265 "b\13EXEC_ENV\0" \
266 "b\15SAUPCALL\0" \
267 "b\16MIB\0" \
268 "b\17EXEC_FD\0" \
269 "f\30\4VERSION\0" \
270 "b\34TRC_EMUL\0" \
271 "b\36INHERIT\0" \
272 "b\37PERSISTENT\0"
273
274/*
275 * trace flags (also in p_traceflags)
276 */
277#define KTRFAC_PERSISTENT 0x80000000 /* persistent trace across sugid
278 exec (exclusive) */
279#define KTRFAC_INHERIT 0x40000000 /* pass trace flags to children */
280#define KTRFAC_TRC_EMUL 0x10000000 /* ktrace KTR_EMUL before next trace */
281#define KTRFAC_VER_MASK 0x0f000000 /* record version mask */
282#define KTRFAC_VER_SHIFT 24 /* record version shift */
283
284#define KTRFAC_VERSION(tf) (((tf) & KTRFAC_VER_MASK) >> KTRFAC_VER_SHIFT)
285
286#define KTRFACv0 (0 << KTRFAC_VER_SHIFT)
287#define KTRFACv1 (1 << KTRFAC_VER_SHIFT)
288#define KTRFACv2 (2 << KTRFAC_VER_SHIFT)
289
290#ifndef _KERNEL
291
292#include <sys/cdefs.h>
293
294__BEGIN_DECLS
295int ktrace(const char *, int, int, pid_t);
296int fktrace(int, int, int, pid_t);
297int utrace(const char *, void *, size_t);
298__END_DECLS
299
300#else
301
302struct syncobj;
303
304void ktrinit(void);
305void ktrderef(struct proc *);
306void ktradref(struct proc *);
307
308extern kmutex_t ktrace_lock;
309extern int ktrace_on;
310
311int ktruser(const char *, void *, size_t, int);
312bool ktr_point(int);
313
314void ktr_csw(int, int, const struct syncobj *);
315void ktr_emul(void);
316void ktr_geniov(int, enum uio_rw, struct iovec *, size_t, int);
317void ktr_genio(int, enum uio_rw, const void *, size_t, int);
318void ktr_mibio(int, enum uio_rw, const void *, size_t, int);
319void ktr_namei(const char *, size_t);
320void ktr_namei2(const char *, size_t, const char *, size_t);
321void ktr_psig(int, sig_t, const sigset_t *, const ksiginfo_t *);
322void ktr_syscall(register_t, const register_t [], int);
323void ktr_sysret(register_t, int, register_t *);
324void ktr_kuser(const char *, const void *, size_t);
325void ktr_mib(const int *a , u_int b);
326void ktr_execarg(const void *, size_t);
327void ktr_execenv(const void *, size_t);
328void ktr_execfd(int, u_int);
329
330int ktrace_common(lwp_t *, int, int, int, file_t **);
331
332static __inline int
333ktrenter(lwp_t *l)
334{
335
336 if ((l->l_pflag & LP_KTRACTIVE) != 0)
337 return 1;
338 l->l_pflag |= LP_KTRACTIVE;
339 return 0;
340}
341
342static __inline void
343ktrexit(lwp_t *l)
344{
345
346 l->l_pflag &= ~LP_KTRACTIVE;
347}
348
349static __inline bool
350ktrpoint(int fac)
351{
352 return __predict_false(ktrace_on) && __predict_false(ktr_point(1 << fac));
353}
354
355static __inline void
356ktrcsw(int a, int b, const struct syncobj *c)
357{
358 if (__predict_false(ktrace_on))
359 ktr_csw(a, b, c);
360}
361
362static __inline void
363ktremul(void)
364{
365 if (__predict_false(ktrace_on))
366 ktr_emul();
367}
368
369static __inline void
370ktrgenio(int a, enum uio_rw b, const void *c, size_t d, int e)
371{
372 if (__predict_false(ktrace_on))
373 ktr_genio(a, b, c, d, e);
374}
375
376static __inline void
377ktrgeniov(int a, enum uio_rw b, struct iovec *c, int d, int e)
378{
379 if (__predict_false(ktrace_on))
380 ktr_geniov(a, b, c, d, e);
381}
382
383static __inline void
384ktrmibio(int a, enum uio_rw b, const void *c, size_t d, int e)
385{
386 if (__predict_false(ktrace_on))
387 ktr_mibio(a, b, c, d, e);
388}
389
390static __inline void
391ktrnamei(const char *a, size_t b)
392{
393 if (__predict_false(ktrace_on))
394 ktr_namei(a, b);
395}
396
397static __inline void
398ktrnamei2(const char *a, size_t b, const char *c, size_t d)
399{
400 if (__predict_false(ktrace_on))
401 ktr_namei2(a, b, c, d);
402}
403
404static __inline void
405ktrpsig(int a, sig_t b, const sigset_t *c, const ksiginfo_t * d)
406{
407 if (__predict_false(ktrace_on))
408 ktr_psig(a, b, c, d);
409}
410
411static __inline void
412ktrsyscall(register_t code, const register_t args[], int narg)
413{
414 if (__predict_false(ktrace_on))
415 ktr_syscall(code, args, narg);
416}
417
418static __inline void
419ktrsysret(register_t a, int b, register_t *c)
420{
421 if (__predict_false(ktrace_on))
422 ktr_sysret(a, b, c);
423}
424
425static __inline void
426ktrkuser(const char *a, const void *b, size_t c)
427{
428 if (__predict_false(ktrace_on))
429 ktr_kuser(a, b, c);
430}
431
432static __inline void
433ktrmib(const int *a , u_int b)
434{
435 if (__predict_false(ktrace_on))
436 ktr_mib(a, b);
437}
438
439static __inline void
440ktrexecarg(const void *a, size_t b)
441{
442 if (__predict_false(ktrace_on))
443 ktr_execarg(a, b);
444}
445
446static __inline void
447ktrexecenv(const void *a, size_t b)
448{
449 if (__predict_false(ktrace_on))
450 ktr_execenv(a, b);
451}
452
453static __inline void
454ktrexecfd(int fd, u_int dtype)
455{
456 if (__predict_false(ktrace_on))
457 ktr_execfd(fd, dtype);
458}
459
460struct ktrace_entry;
461int ktealloc(struct ktrace_entry **, void **, lwp_t *, int, size_t);
462void ktesethdrlen(struct ktrace_entry *, size_t);
463void ktraddentry(lwp_t *, struct ktrace_entry *, int);
464/* Flags for ktraddentry (3rd arg) */
465#define KTA_NOWAIT 0x0000
466#define KTA_WAITOK 0x0001
467#define KTA_LARGE 0x0002
468
469#endif /* !_KERNEL */
470
471#endif /* _SYS_KTRACE_H_ */