1/*
2 * Copyright 2001 Jamey Wood
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * $FreeBSD$
26 */
27
28#include <sys/linker_set.h>
29#include <sys/queue.h>
30
31#define	FOLLOWFORKS		0x00000001
32#define	RELATIVETIMESTAMPS	0x00000002
33#define	ABSOLUTETIMESTAMPS	0x00000004
34#define	NOSIGS			0x00000008
35#define	EXECVEARGS		0x00000010
36#define	EXECVEENVS		0x00000020
37#define	COUNTONLY		0x00000040
38#define	DISPLAYTIDS		0x00000080
39
40struct procinfo;
41struct trussinfo;
42
43struct procabi {
44	const char *type;
45	const char **syscallnames;
46	int nsyscalls;
47	int (*fetch_args)(struct trussinfo *, u_int);
48	int (*fetch_retval)(struct trussinfo *, long *, int *);
49};
50
51#define	PROCABI(abi)	DATA_SET(procabi, abi)
52
53/*
54 * This is confusingly named.  It holds per-thread state about the
55 * currently executing system call.  syscall.h defines a struct
56 * syscall that holds metadata used to format system call arguments.
57 *
58 * NB: args[] stores the raw argument values (e.g. from registers)
59 * passed to the system call.  s_args[] stores a string representation
60 * of a system call's arguments.  These do not necessarily map one to
61 * one.  A system call description may omit individual arguments
62 * (padding) or combine adjacent arguments (e.g. when passing an off_t
63 * argument on a 32-bit system).  The nargs member contains the count
64 * of valid pointers in s_args[], not args[].
65 */
66struct current_syscall {
67	struct syscall *sc;
68	const char *name;
69	int number;
70	unsigned long args[10];
71	unsigned int nargs;
72	char *s_args[10];	/* the printable arguments */
73};
74
75struct threadinfo
76{
77	SLIST_ENTRY(threadinfo) entries;
78	struct procinfo *proc;
79	lwpid_t tid;
80	int in_syscall;
81	struct current_syscall cs;
82	struct timespec before;
83	struct timespec after;
84};
85
86struct procinfo {
87	LIST_ENTRY(procinfo) entries;
88	pid_t pid;
89	struct procabi *abi;
90
91	SLIST_HEAD(, threadinfo) threadlist;
92};
93
94struct trussinfo
95{
96	int flags;
97	int strsize;
98	FILE *outfile;
99
100	struct timespec start_time;
101
102	struct threadinfo *curthread;
103
104	LIST_HEAD(, procinfo) proclist;
105};
106
107#define	timespecsubt(tvp, uvp, vvp)					\
108	do {								\
109		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
110		(vvp)->tv_nsec = (tvp)->tv_nsec - (uvp)->tv_nsec;	\
111		if ((vvp)->tv_nsec < 0) {				\
112			(vvp)->tv_sec--;				\
113			(vvp)->tv_nsec += 1000000000;			\
114		}							\
115	} while (0)
116
117#define	timespecadd(tvp, uvp, vvp)					\
118	do {								\
119		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
120		(vvp)->tv_nsec = (tvp)->tv_nsec + (uvp)->tv_nsec;	\
121		if ((vvp)->tv_nsec > 1000000000) {				\
122			(vvp)->tv_sec++;				\
123			(vvp)->tv_nsec -= 1000000000;			\
124		}							\
125	} while (0)
126