xref: /freebsd/usr.bin/truss/syscalls.c (revision ecac235bb0253f5a08371f565eac9468946c973b)
1bbeaf6c0SSean Eric Fagan /*
20a6c71f8SWarner Losh  * Copyright 1997 Sean Eric Fagan
309d64da3SSean Eric Fagan  *
409d64da3SSean Eric Fagan  * Redistribution and use in source and binary forms, with or without
509d64da3SSean Eric Fagan  * modification, are permitted provided that the following conditions
609d64da3SSean Eric Fagan  * are met:
709d64da3SSean Eric Fagan  * 1. Redistributions of source code must retain the above copyright
809d64da3SSean Eric Fagan  *    notice, this list of conditions and the following disclaimer.
909d64da3SSean Eric Fagan  * 2. Redistributions in binary form must reproduce the above copyright
1009d64da3SSean Eric Fagan  *    notice, this list of conditions and the following disclaimer in the
1109d64da3SSean Eric Fagan  *    documentation and/or other materials provided with the distribution.
1209d64da3SSean Eric Fagan  * 3. All advertising materials mentioning features or use of this software
1309d64da3SSean Eric Fagan  *    must display the following acknowledgement:
1409d64da3SSean Eric Fagan  *	This product includes software developed by Sean Eric Fagan
1509d64da3SSean Eric Fagan  * 4. Neither the name of the author may be used to endorse or promote
1609d64da3SSean Eric Fagan  *    products derived from this software without specific prior written
1709d64da3SSean Eric Fagan  *    permission.
1809d64da3SSean Eric Fagan  *
1909d64da3SSean Eric Fagan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2009d64da3SSean Eric Fagan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2109d64da3SSean Eric Fagan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2209d64da3SSean Eric Fagan  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2309d64da3SSean Eric Fagan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2409d64da3SSean Eric Fagan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2509d64da3SSean Eric Fagan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2609d64da3SSean Eric Fagan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2709d64da3SSean Eric Fagan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2809d64da3SSean Eric Fagan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2909d64da3SSean Eric Fagan  * SUCH DAMAGE.
3009d64da3SSean Eric Fagan  */
3109d64da3SSean Eric Fagan 
322b75c8adSJohn Baldwin #include <sys/cdefs.h>
332b75c8adSJohn Baldwin __FBSDID("$FreeBSD$");
343cf51049SPhilippe Charnier 
3509d64da3SSean Eric Fagan /*
36bbeaf6c0SSean Eric Fagan  * This file has routines used to print out system calls and their
37bbeaf6c0SSean Eric Fagan  * arguments.
38bbeaf6c0SSean Eric Fagan  */
39bbeaf6c0SSean Eric Fagan 
409ddd1412SDag-Erling Smørgrav #include <sys/types.h>
412b75c8adSJohn Baldwin #include <sys/event.h>
422b75c8adSJohn Baldwin #include <sys/ioccom.h>
43a776866bSBryan Drewery #include <sys/mount.h>
445d2d083cSXin LI #include <sys/ptrace.h>
452b75c8adSJohn Baldwin #include <sys/resource.h>
469ddd1412SDag-Erling Smørgrav #include <sys/socket.h>
472b75c8adSJohn Baldwin #include <sys/stat.h>
489ddd1412SDag-Erling Smørgrav #include <sys/un.h>
4934763d1cSJohn Baldwin #include <sys/wait.h>
502b75c8adSJohn Baldwin #include <machine/sysarch.h>
519ddd1412SDag-Erling Smørgrav #include <netinet/in.h>
529ddd1412SDag-Erling Smørgrav #include <arpa/inet.h>
539ddd1412SDag-Erling Smørgrav 
541175b23fSJohn Baldwin #include <assert.h>
55dec17687SBrian Feldman #include <ctype.h>
563cf51049SPhilippe Charnier #include <err.h>
57894b8f7aSAlfred Perlstein #include <fcntl.h>
58e45a5a0dSDavid Malone #include <poll.h>
599ddd1412SDag-Erling Smørgrav #include <signal.h>
60808d9805SEd Schouten #include <stdbool.h>
61bbeaf6c0SSean Eric Fagan #include <stdio.h>
62bbeaf6c0SSean Eric Fagan #include <stdlib.h>
63bbeaf6c0SSean Eric Fagan #include <string.h>
64d6fb4894SJohn Baldwin #include <sysdecode.h>
65bbeaf6c0SSean Eric Fagan #include <unistd.h>
66081e5c48SPav Lucistnik #include <vis.h>
679ddd1412SDag-Erling Smørgrav 
681f3bbfd8SEd Schouten #include <contrib/cloudabi/cloudabi_types_common.h>
69808d9805SEd Schouten 
70ec0bed25SMatthew N. Dodd #include "truss.h"
711be5d704SMark Murray #include "extern.h"
72bbeaf6c0SSean Eric Fagan #include "syscall.h"
73bbeaf6c0SSean Eric Fagan 
74bbeaf6c0SSean Eric Fagan /*
75081e5c48SPav Lucistnik  * This should probably be in its own file, sorted alphabetically.
76bbeaf6c0SSean Eric Fagan  */
776c61b0f3SBryan Drewery static struct syscall decoded_syscalls[] = {
78f44fc79dSJohn Baldwin 	/* Native ABI */
79f44fc79dSJohn Baldwin 	{ .name = "__getcwd", .ret_type = 1, .nargs = 2,
80f44fc79dSJohn Baldwin 	  .args = { { Name | OUT, 0 }, { Int, 1 } } },
81f44fc79dSJohn Baldwin 	{ .name = "_umtx_op", .ret_type = 1, .nargs = 5,
82f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 },
83f44fc79dSJohn Baldwin 		    { Ptr, 4 } } },
84f44fc79dSJohn Baldwin 	{ .name = "accept", .ret_type = 1, .nargs = 3,
85f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
86f44fc79dSJohn Baldwin 	{ .name = "access", .ret_type = 1, .nargs = 2,
87f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Accessmode, 1 } } },
88f44fc79dSJohn Baldwin 	{ .name = "bind", .ret_type = 1, .nargs = 3,
8958227c60SMichael Tuexen 	  .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Socklent, 2 } } },
90f44fc79dSJohn Baldwin 	{ .name = "bindat", .ret_type = 1, .nargs = 4,
91f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 },
927d897327SJohn Baldwin 		    { Int, 3 } } },
93f44fc79dSJohn Baldwin 	{ .name = "break", .ret_type = 1, .nargs = 1,
94f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 } } },
95bed418c8SJohn Baldwin 	{ .name = "cap_fcntls_get", .ret_type = 1, .nargs = 2,
96bed418c8SJohn Baldwin 	  .args = { { Int, 0 }, { CapFcntlRights | OUT, 1 } } },
97bed418c8SJohn Baldwin 	{ .name = "cap_fcntls_limit", .ret_type = 1, .nargs = 2,
98bed418c8SJohn Baldwin 	  .args = { { Int, 0 }, { CapFcntlRights, 1 } } },
99f44fc79dSJohn Baldwin 	{ .name = "chdir", .ret_type = 1, .nargs = 1,
100f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
101f44fc79dSJohn Baldwin 	{ .name = "chflags", .ret_type = 1, .nargs = 2,
10227459358SJohn Baldwin 	  .args = { { Name | IN, 0 }, { FileFlags, 1 } } },
10327459358SJohn Baldwin 	{ .name = "chflagsat", .ret_type = 1, .nargs = 4,
10427459358SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { FileFlags, 2 },
10527459358SJohn Baldwin 		    { Atflags, 3 } } },
106f44fc79dSJohn Baldwin 	{ .name = "chmod", .ret_type = 1, .nargs = 2,
107ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Octal, 1 } } },
108f44fc79dSJohn Baldwin 	{ .name = "chown", .ret_type = 1, .nargs = 3,
109f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
110f44fc79dSJohn Baldwin 	{ .name = "chroot", .ret_type = 1, .nargs = 1,
111f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
112f44fc79dSJohn Baldwin 	{ .name = "clock_gettime", .ret_type = 1, .nargs = 2,
113f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timespec | OUT, 1 } } },
114ee3b0f6eSDiomidis Spinellis 	{ .name = "close", .ret_type = 1, .nargs = 1,
115ee3b0f6eSDiomidis Spinellis 	  .args = { { Int, 0 } } },
116f44fc79dSJohn Baldwin 	{ .name = "connect", .ret_type = 1, .nargs = 3,
11758227c60SMichael Tuexen 	  .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Socklent, 2 } } },
118f44fc79dSJohn Baldwin 	{ .name = "connectat", .ret_type = 1, .nargs = 4,
119f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 },
120f44fc79dSJohn Baldwin 		    { Int, 3 } } },
121f44fc79dSJohn Baldwin 	{ .name = "eaccess", .ret_type = 1, .nargs = 2,
122f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Accessmode, 1 } } },
123f44fc79dSJohn Baldwin 	{ .name = "execve", .ret_type = 1, .nargs = 3,
124f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
125f44fc79dSJohn Baldwin 		    { ExecEnv | IN, 2 } } },
126f44fc79dSJohn Baldwin 	{ .name = "exit", .ret_type = 0, .nargs = 1,
127f44fc79dSJohn Baldwin 	  .args = { { Hex, 0 } } },
128f44fc79dSJohn Baldwin 	{ .name = "faccessat", .ret_type = 1, .nargs = 4,
129f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 },
130f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
13127459358SJohn Baldwin 	{ .name = "fchflags", .ret_type = 1, .nargs = 2,
13227459358SJohn Baldwin 	  .args = { { Int, 0 }, { FileFlags, 1 } } },
133f44fc79dSJohn Baldwin 	{ .name = "fchmod", .ret_type = 1, .nargs = 2,
134f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Octal, 1 } } },
135f44fc79dSJohn Baldwin 	{ .name = "fchmodat", .ret_type = 1, .nargs = 4,
136f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Atflags, 3 } } },
137f44fc79dSJohn Baldwin 	{ .name = "fchown", .ret_type = 1, .nargs = 3,
138f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } },
139f44fc79dSJohn Baldwin 	{ .name = "fchownat", .ret_type = 1, .nargs = 5,
140f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 },
141f44fc79dSJohn Baldwin 		    { Atflags, 4 } } },
142f44fc79dSJohn Baldwin 	{ .name = "fcntl", .ret_type = 1, .nargs = 3,
143f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } },
144dd92181fSJohn Baldwin 	{ .name = "flock", .ret_type = 1, .nargs = 2,
145dd92181fSJohn Baldwin 	  .args = { { Int, 0 }, { Flockop, 1 } } },
146f44fc79dSJohn Baldwin 	{ .name = "fstat", .ret_type = 1, .nargs = 2,
147f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Stat | OUT, 1 } } },
148f44fc79dSJohn Baldwin 	{ .name = "fstatat", .ret_type = 1, .nargs = 4,
149f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat | OUT, 2 },
150f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
151f44fc79dSJohn Baldwin 	{ .name = "fstatfs", .ret_type = 1, .nargs = 2,
152f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { StatFs | OUT, 1 } } },
153f44fc79dSJohn Baldwin 	{ .name = "ftruncate", .ret_type = 1, .nargs = 2,
154c05cc0d6SJohn Baldwin 	  .args = { { Int | IN, 0 }, { QuadHex | IN, 1 } } },
155f44fc79dSJohn Baldwin 	{ .name = "futimens", .ret_type = 1, .nargs = 2,
156f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timespec2 | IN, 1 } } },
157f44fc79dSJohn Baldwin 	{ .name = "futimes", .ret_type = 1, .nargs = 2,
158f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timeval2 | IN, 1 } } },
159f44fc79dSJohn Baldwin 	{ .name = "futimesat", .ret_type = 1, .nargs = 3,
160f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timeval2 | IN, 2 } } },
161ab43bedcSJohn Baldwin 	{ .name = "getfsstat", .ret_type = 1, .nargs = 3,
162ab43bedcSJohn Baldwin 	  .args = { { Ptr, 0 }, { Long, 1 }, { Getfsstatmode, 2 } } },
163f44fc79dSJohn Baldwin 	{ .name = "getitimer", .ret_type = 1, .nargs = 2,
164f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Itimerval | OUT, 2 } } },
165f44fc79dSJohn Baldwin 	{ .name = "getpeername", .ret_type = 1, .nargs = 3,
166f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
167f44fc79dSJohn Baldwin 	{ .name = "getpgid", .ret_type = 1, .nargs = 1,
168f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
169f44fc79dSJohn Baldwin 	{ .name = "getrlimit", .ret_type = 1, .nargs = 2,
170f44fc79dSJohn Baldwin 	  .args = { { Resource, 0 }, { Rlimit | OUT, 1 } } },
171f44fc79dSJohn Baldwin 	{ .name = "getrusage", .ret_type = 1, .nargs = 2,
172f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Rusage | OUT, 1 } } },
173f44fc79dSJohn Baldwin 	{ .name = "getsid", .ret_type = 1, .nargs = 1,
174f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
175f44fc79dSJohn Baldwin 	{ .name = "getsockname", .ret_type = 1, .nargs = 3,
176f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
177f44fc79dSJohn Baldwin 	{ .name = "gettimeofday", .ret_type = 1, .nargs = 2,
178f44fc79dSJohn Baldwin 	  .args = { { Timeval | OUT, 0 }, { Ptr, 1 } } },
179f44fc79dSJohn Baldwin 	{ .name = "ioctl", .ret_type = 1, .nargs = 3,
180a776eeafSJohn Baldwin 	  .args = { { Int, 0 }, { Ioctl, 1 }, { Ptr, 2 } } },
181f44fc79dSJohn Baldwin 	{ .name = "kevent", .ret_type = 1, .nargs = 6,
182f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 },
183f44fc79dSJohn Baldwin 		    { Int, 4 }, { Timespec, 5 } } },
184f44fc79dSJohn Baldwin 	{ .name = "kill", .ret_type = 1, .nargs = 2,
185f44fc79dSJohn Baldwin 	  .args = { { Int | IN, 0 }, { Signal | IN, 1 } } },
186f44fc79dSJohn Baldwin 	{ .name = "kldfind", .ret_type = 1, .nargs = 1,
187f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
188f44fc79dSJohn Baldwin 	{ .name = "kldfirstmod", .ret_type = 1, .nargs = 1,
189f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
190f44fc79dSJohn Baldwin 	{ .name = "kldload", .ret_type = 1, .nargs = 1,
191f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
192f44fc79dSJohn Baldwin 	{ .name = "kldnext", .ret_type = 1, .nargs = 1,
193f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
194f44fc79dSJohn Baldwin 	{ .name = "kldstat", .ret_type = 1, .nargs = 2,
195f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr, 1 } } },
19694e854c5SJohn Baldwin 	{ .name = "kldsym", .ret_type = 1, .nargs = 3,
19794e854c5SJohn Baldwin 	  .args = { { Int, 0 }, { Kldsymcmd, 1 }, { Ptr, 2 } } },
198f44fc79dSJohn Baldwin 	{ .name = "kldunload", .ret_type = 1, .nargs = 1,
199f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
20094e854c5SJohn Baldwin 	{ .name = "kldunloadf", .ret_type = 1, .nargs = 2,
20194e854c5SJohn Baldwin 	  .args = { { Int, 0 }, { Kldunloadflags, 1 } } },
202f44fc79dSJohn Baldwin 	{ .name = "kse_release", .ret_type = 0, .nargs = 1,
203f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
204f44fc79dSJohn Baldwin 	{ .name = "lchflags", .ret_type = 1, .nargs = 2,
20527459358SJohn Baldwin 	  .args = { { Name | IN, 0 }, { FileFlags, 1 } } },
206f44fc79dSJohn Baldwin 	{ .name = "lchmod", .ret_type = 1, .nargs = 2,
207f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
208f44fc79dSJohn Baldwin 	{ .name = "lchown", .ret_type = 1, .nargs = 3,
209f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
2102b75c8adSJohn Baldwin 	{ .name = "link", .ret_type = 1, .nargs = 2,
211ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
2122b75c8adSJohn Baldwin 	{ .name = "linkat", .ret_type = 1, .nargs = 5,
2137d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 },
2147d897327SJohn Baldwin 		    { Atflags, 4 } } },
215e8d2c81dSMichael Tuexen 	{ .name = "listen", .ret_type = 1, .nargs = 2,
216e8d2c81dSMichael Tuexen 	  .args = { { Int, 0 }, { Int, 1 } } },
217f44fc79dSJohn Baldwin  	{ .name = "lseek", .ret_type = 2, .nargs = 3,
218c05cc0d6SJohn Baldwin 	  .args = { { Int, 0 }, { QuadHex, 1 }, { Whence, 2 } } },
219f44fc79dSJohn Baldwin 	{ .name = "lstat", .ret_type = 1, .nargs = 2,
220f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
221f44fc79dSJohn Baldwin 	{ .name = "lutimes", .ret_type = 1, .nargs = 2,
222f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
22398fdbeecSJohn Baldwin 	{ .name = "madvise", .ret_type = 1, .nargs = 3,
22498fdbeecSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Madvice, 2 } } },
225f44fc79dSJohn Baldwin 	{ .name = "mkdir", .ret_type = 1, .nargs = 2,
226f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
227f44fc79dSJohn Baldwin 	{ .name = "mkdirat", .ret_type = 1, .nargs = 3,
228f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
2292b75c8adSJohn Baldwin 	{ .name = "mkfifo", .ret_type = 1, .nargs = 2,
230e82ce59cSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
2312b75c8adSJohn Baldwin 	{ .name = "mkfifoat", .ret_type = 1, .nargs = 3,
2327d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
2332b75c8adSJohn Baldwin 	{ .name = "mknod", .ret_type = 1, .nargs = 3,
234e82ce59cSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } },
2352b75c8adSJohn Baldwin 	{ .name = "mknodat", .ret_type = 1, .nargs = 4,
2367d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } },
237f44fc79dSJohn Baldwin 	{ .name = "mmap", .ret_type = 1, .nargs = 6,
238e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Mprot, 2 }, { Mmapflags, 3 },
239c05cc0d6SJohn Baldwin 		    { Int, 4 }, { QuadHex, 5 } } },
240f44fc79dSJohn Baldwin 	{ .name = "modfind", .ret_type = 1, .nargs = 1,
241f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
2422b75c8adSJohn Baldwin 	{ .name = "mount", .ret_type = 1, .nargs = 4,
243ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } },
244f44fc79dSJohn Baldwin 	{ .name = "mprotect", .ret_type = 1, .nargs = 3,
245e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Mprot, 2 } } },
246f44fc79dSJohn Baldwin 	{ .name = "munmap", .ret_type = 1, .nargs = 2,
247e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 } } },
248f44fc79dSJohn Baldwin 	{ .name = "nanosleep", .ret_type = 1, .nargs = 1,
249f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
250f44fc79dSJohn Baldwin 	{ .name = "open", .ret_type = 1, .nargs = 3,
251f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } },
252f44fc79dSJohn Baldwin 	{ .name = "openat", .ret_type = 1, .nargs = 4,
253f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Open, 2 },
254f44fc79dSJohn Baldwin 		    { Octal, 3 } } },
255f44fc79dSJohn Baldwin 	{ .name = "pathconf", .ret_type = 1, .nargs = 2,
256f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Pathconf, 1 } } },
257f44fc79dSJohn Baldwin 	{ .name = "pipe", .ret_type = 1, .nargs = 1,
258f44fc79dSJohn Baldwin 	  .args = { { PipeFds | OUT, 0 } } },
259f44fc79dSJohn Baldwin 	{ .name = "pipe2", .ret_type = 1, .nargs = 2,
2609289f547SJohn Baldwin 	  .args = { { Ptr, 0 }, { Pipe2, 1 } } },
261f44fc79dSJohn Baldwin 	{ .name = "poll", .ret_type = 1, .nargs = 3,
262f44fc79dSJohn Baldwin 	  .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } },
263d2a97485SJohn Baldwin 	{ .name = "posix_fadvise", .ret_type = 1, .nargs = 4,
264d2a97485SJohn Baldwin 	  .args = { { Int, 0 }, { QuadHex, 1 }, { QuadHex, 2 },
265d2a97485SJohn Baldwin 		    { Fadvice, 3 } } },
266f44fc79dSJohn Baldwin 	{ .name = "posix_openpt", .ret_type = 1, .nargs = 1,
267f44fc79dSJohn Baldwin 	  .args = { { Open, 0 } } },
268f44fc79dSJohn Baldwin 	{ .name = "procctl", .ret_type = 1, .nargs = 4,
269c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { Procctl, 2 }, { Ptr, 3 } } },
270f44fc79dSJohn Baldwin 	{ .name = "read", .ret_type = 1, .nargs = 3,
271e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 } } },
272f44fc79dSJohn Baldwin 	{ .name = "readlink", .ret_type = 1, .nargs = 3,
273e261fb2aSJohn Baldwin 	  .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Sizet, 2 } } },
274f44fc79dSJohn Baldwin 	{ .name = "readlinkat", .ret_type = 1, .nargs = 4,
275f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 },
276e261fb2aSJohn Baldwin 		    { Sizet, 3 } } },
277ee3b0f6eSDiomidis Spinellis 	{ .name = "recvfrom", .ret_type = 1, .nargs = 6,
278e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 }, { Hex, 3 },
2790a46af44SJohn Baldwin 		    { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } },
280f44fc79dSJohn Baldwin 	{ .name = "rename", .ret_type = 1, .nargs = 2,
281f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Name, 1 } } },
282f44fc79dSJohn Baldwin 	{ .name = "renameat", .ret_type = 1, .nargs = 4,
283f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 } } },
284f44fc79dSJohn Baldwin 	{ .name = "rfork", .ret_type = 1, .nargs = 1,
285f44fc79dSJohn Baldwin 	  .args = { { Rforkflags, 0 } } },
286cca89ee3SBryan Drewery 	{ .name = "rmdir", .ret_type = 1, .nargs = 1,
287cca89ee3SBryan Drewery 	  .args = { { Name, 0 } } },
288ee3b0f6eSDiomidis Spinellis 	{ .name = "select", .ret_type = 1, .nargs = 5,
2890a46af44SJohn Baldwin 	  .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 },
2900a46af44SJohn Baldwin 		    { Timeval, 4 } } },
291f44fc79dSJohn Baldwin 	{ .name = "sendto", .ret_type = 1, .nargs = 6,
292e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 }, { Hex, 3 },
29358227c60SMichael Tuexen 		    { Sockaddr | IN, 4 }, { Socklent | IN, 5 } } },
294ee3b0f6eSDiomidis Spinellis 	{ .name = "setitimer", .ret_type = 1, .nargs = 3,
295ee3b0f6eSDiomidis Spinellis 	  .args = { { Int, 0 }, { Itimerval, 1 }, { Itimerval | OUT, 2 } } },
296f44fc79dSJohn Baldwin 	{ .name = "setrlimit", .ret_type = 1, .nargs = 2,
297f44fc79dSJohn Baldwin 	  .args = { { Resource, 0 }, { Rlimit | IN, 1 } } },
298f44fc79dSJohn Baldwin 	{ .name = "shutdown", .ret_type = 1, .nargs = 2,
299f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Shutdown, 1 } } },
300f44fc79dSJohn Baldwin 	{ .name = "sigaction", .ret_type = 1, .nargs = 3,
301f44fc79dSJohn Baldwin 	  .args = { { Signal, 0 }, { Sigaction | IN, 1 },
302f44fc79dSJohn Baldwin 		    { Sigaction | OUT, 2 } } },
3032b75c8adSJohn Baldwin 	{ .name = "sigpending", .ret_type = 1, .nargs = 1,
304b289a8d7SJohn Baldwin 	  .args = { { Sigset | OUT, 0 } } },
3052b75c8adSJohn Baldwin 	{ .name = "sigprocmask", .ret_type = 1, .nargs = 3,
306ee3b0f6eSDiomidis Spinellis 	  .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } },
3072b75c8adSJohn Baldwin 	{ .name = "sigqueue", .ret_type = 1, .nargs = 3,
308b289a8d7SJohn Baldwin 	  .args = { { Int, 0 }, { Signal, 1 }, { LongHex, 2 } } },
3092b75c8adSJohn Baldwin 	{ .name = "sigreturn", .ret_type = 1, .nargs = 1,
310b289a8d7SJohn Baldwin 	  .args = { { Ptr, 0 } } },
3112b75c8adSJohn Baldwin 	{ .name = "sigsuspend", .ret_type = 1, .nargs = 1,
312b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 } } },
313b289a8d7SJohn Baldwin 	{ .name = "sigtimedwait", .ret_type = 1, .nargs = 3,
314b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 }, { Timespec | IN, 2 } } },
315b289a8d7SJohn Baldwin 	{ .name = "sigwait", .ret_type = 1, .nargs = 2,
316b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 } } },
317b289a8d7SJohn Baldwin 	{ .name = "sigwaitinfo", .ret_type = 1, .nargs = 2,
318b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 } } },
319ee3b0f6eSDiomidis Spinellis 	{ .name = "socket", .ret_type = 1, .nargs = 3,
320*ecac235bSMichael Tuexen 	  .args = { { Sockdomain, 0 }, { Socktype, 1 }, { Sockprotocol, 2 } } },
321f44fc79dSJohn Baldwin 	{ .name = "stat", .ret_type = 1, .nargs = 2,
322f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
323f44fc79dSJohn Baldwin 	{ .name = "statfs", .ret_type = 1, .nargs = 2,
324f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { StatFs | OUT, 1 } } },
325ee3b0f6eSDiomidis Spinellis 	{ .name = "symlink", .ret_type = 1, .nargs = 2,
326ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
3277d897327SJohn Baldwin 	{ .name = "symlinkat", .ret_type = 1, .nargs = 3,
3287d897327SJohn Baldwin 	  .args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } },
329f44fc79dSJohn Baldwin 	{ .name = "sysarch", .ret_type = 1, .nargs = 2,
330f44fc79dSJohn Baldwin 	  .args = { { Sysarch, 0 }, { Ptr, 1 } } },
331f44fc79dSJohn Baldwin 	{ .name = "thr_kill", .ret_type = 1, .nargs = 2,
332f44fc79dSJohn Baldwin 	  .args = { { Long, 0 }, { Signal, 1 } } },
333f44fc79dSJohn Baldwin 	{ .name = "thr_self", .ret_type = 1, .nargs = 1,
334f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 } } },
335f44fc79dSJohn Baldwin 	{ .name = "truncate", .ret_type = 1, .nargs = 2,
336c05cc0d6SJohn Baldwin 	  .args = { { Name | IN, 0 }, { QuadHex | IN, 1 } } },
337f44fc79dSJohn Baldwin #if 0
338f44fc79dSJohn Baldwin 	/* Does not exist */
339f44fc79dSJohn Baldwin 	{ .name = "umount", .ret_type = 1, .nargs = 2,
340f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 2 } } },
341f44fc79dSJohn Baldwin #endif
342f44fc79dSJohn Baldwin 	{ .name = "unlink", .ret_type = 1, .nargs = 1,
343f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
344f44fc79dSJohn Baldwin 	{ .name = "unlinkat", .ret_type = 1, .nargs = 3,
345f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } },
346f44fc79dSJohn Baldwin 	{ .name = "unmount", .ret_type = 1, .nargs = 2,
347f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 } } },
348f44fc79dSJohn Baldwin 	{ .name = "utimensat", .ret_type = 1, .nargs = 4,
349f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 },
350f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
351f44fc79dSJohn Baldwin 	{ .name = "utimes", .ret_type = 1, .nargs = 2,
352f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
353195aef99SBryan Drewery 	{ .name = "utrace", .ret_type = 1, .nargs = 1,
354195aef99SBryan Drewery 	  .args = { { Utrace, 0 } } },
35534763d1cSJohn Baldwin 	{ .name = "wait4", .ret_type = 1, .nargs = 4,
35634763d1cSJohn Baldwin 	  .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 },
35734763d1cSJohn Baldwin 		    { Rusage | OUT, 3 } } },
35834763d1cSJohn Baldwin 	{ .name = "wait6", .ret_type = 1, .nargs = 6,
359c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { ExitStatus | OUT, 2 },
360c05cc0d6SJohn Baldwin 		    { Waitoptions, 3 }, { Rusage | OUT, 4 }, { Ptr, 5 } } },
361f44fc79dSJohn Baldwin 	{ .name = "write", .ret_type = 1, .nargs = 3,
362e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 } } },
363f44fc79dSJohn Baldwin 
364f44fc79dSJohn Baldwin 	/* Linux ABI */
365f44fc79dSJohn Baldwin 	{ .name = "linux_access", .ret_type = 1, .nargs = 2,
366f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Accessmode, 1 } } },
367f44fc79dSJohn Baldwin 	{ .name = "linux_execve", .ret_type = 1, .nargs = 3,
368f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
369f44fc79dSJohn Baldwin 		    { ExecEnv | IN, 2 } } },
370f44fc79dSJohn Baldwin 	{ .name = "linux_lseek", .ret_type = 2, .nargs = 3,
371f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } },
372f44fc79dSJohn Baldwin 	{ .name = "linux_mkdir", .ret_type = 1, .nargs = 2,
373f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Int, 1 } } },
374f44fc79dSJohn Baldwin 	{ .name = "linux_newfstat", .ret_type = 1, .nargs = 2,
375f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr | OUT, 1 } } },
376f44fc79dSJohn Baldwin 	{ .name = "linux_newstat", .ret_type = 1, .nargs = 2,
377f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
378f44fc79dSJohn Baldwin 	{ .name = "linux_open", .ret_type = 1, .nargs = 3,
379f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } },
380f44fc79dSJohn Baldwin 	{ .name = "linux_readlink", .ret_type = 1, .nargs = 3,
381e261fb2aSJohn Baldwin 	  .args = { { Name, 0 }, { Name | OUT, 1 }, { Sizet, 2 } } },
382f44fc79dSJohn Baldwin 	{ .name = "linux_socketcall", .ret_type = 1, .nargs = 2,
383f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { LinuxSockArgs, 1 } } },
38464f4703bSJohn Baldwin 	{ .name = "linux_stat64", .ret_type = 1, .nargs = 2,
38564f4703bSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
386f44fc79dSJohn Baldwin 
387808d9805SEd Schouten 	/* CloudABI system calls. */
388808d9805SEd Schouten 	{ .name = "cloudabi_sys_clock_res_get", .ret_type = 1, .nargs = 1,
389808d9805SEd Schouten 	  .args = { { CloudABIClockID, 0 } } },
390808d9805SEd Schouten 	{ .name = "cloudabi_sys_clock_time_get", .ret_type = 1, .nargs = 2,
391808d9805SEd Schouten 	  .args = { { CloudABIClockID, 0 }, { CloudABITimestamp, 1 } } },
392808d9805SEd Schouten 	{ .name = "cloudabi_sys_condvar_signal", .ret_type = 1, .nargs = 3,
393808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 }, { UInt, 2 } } },
394808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_close", .ret_type = 1, .nargs = 1,
395808d9805SEd Schouten 	  .args = { { Int, 0 } } },
396808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_create1", .ret_type = 1, .nargs = 1,
397808d9805SEd Schouten 	  .args = { { CloudABIFileType, 0 } } },
398808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_create2", .ret_type = 1, .nargs = 2,
399808d9805SEd Schouten 	  .args = { { CloudABIFileType, 0 }, { PipeFds | OUT, 0 } } },
400808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_datasync", .ret_type = 1, .nargs = 1,
401808d9805SEd Schouten 	  .args = { { Int, 0 } } },
402808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_dup", .ret_type = 1, .nargs = 1,
403808d9805SEd Schouten 	  .args = { { Int, 0 } } },
404808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_replace", .ret_type = 1, .nargs = 2,
405808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 } } },
406808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_seek", .ret_type = 1, .nargs = 3,
407808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { CloudABIWhence, 2 } } },
408808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_stat_get", .ret_type = 1, .nargs = 2,
409808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFDStat | OUT, 1 } } },
410808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_stat_put", .ret_type = 1, .nargs = 3,
411808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFDStat | IN, 1 },
412808d9805SEd Schouten 	            { ClouduABIFDSFlags, 2 } } },
413808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_sync", .ret_type = 1, .nargs = 1,
414808d9805SEd Schouten 	  .args = { { Int, 0 } } },
415808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_advise", .ret_type = 1, .nargs = 4,
416808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 },
417808d9805SEd Schouten 	            { CloudABIAdvice, 3 } } },
418808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_allocate", .ret_type = 1, .nargs = 3,
419808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } },
420808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_create", .ret_type = 1, .nargs = 3,
421808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
422808d9805SEd Schouten 	            { CloudABIFileType, 3 } } },
423808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_link", .ret_type = 1, .nargs = 4,
424808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
425808d9805SEd Schouten 	            { Int, 3 }, { BinString | IN, 4 } } },
426808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_open", .ret_type = 1, .nargs = 4,
427808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
428808d9805SEd Schouten 	            { CloudABIOFlags, 3 }, { CloudABIFDStat | IN, 4 } } },
429808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_readdir", .ret_type = 1, .nargs = 4,
430808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 },
431808d9805SEd Schouten 	            { Int, 3 } } },
432808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_readlink", .ret_type = 1, .nargs = 4,
433808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
434808d9805SEd Schouten 	            { BinString | OUT, 3 }, { Int, 4 } } },
435808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_rename", .ret_type = 1, .nargs = 4,
436808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
437808d9805SEd Schouten 	            { Int, 3 }, { BinString | IN, 4 } } },
438808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_fget", .ret_type = 1, .nargs = 2,
439808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFileStat | OUT, 1 } } },
440808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_fput", .ret_type = 1, .nargs = 3,
441808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFileStat | IN, 1 },
442808d9805SEd Schouten 	            { CloudABIFSFlags, 2 } } },
443808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_get", .ret_type = 1, .nargs = 3,
444808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
445808d9805SEd Schouten 	            { CloudABIFileStat | OUT, 3 } } },
446808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_put", .ret_type = 1, .nargs = 4,
447808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
448808d9805SEd Schouten 	            { CloudABIFileStat | IN, 3 }, { CloudABIFSFlags, 4 } } },
449808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_symlink", .ret_type = 1, .nargs = 3,
450808d9805SEd Schouten 	  .args = { { BinString | IN, 0 },
451808d9805SEd Schouten 	            { Int, 2 }, { BinString | IN, 3 } } },
452808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_unlink", .ret_type = 1, .nargs = 3,
453808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
454808d9805SEd Schouten 	            { CloudABIULFlags, 3 } } },
455808d9805SEd Schouten 	{ .name = "cloudabi_sys_lock_unlock", .ret_type = 1, .nargs = 2,
456808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } },
457808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_advise", .ret_type = 1, .nargs = 3,
458808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIAdvice, 2 } } },
459808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_lock", .ret_type = 1, .nargs = 2,
460808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
461808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_map", .ret_type = 1, .nargs = 6,
462808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 },
463808d9805SEd Schouten 	            { CloudABIMFlags, 3 }, { Int, 4 }, { Int, 5 } } },
464808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_protect", .ret_type = 1, .nargs = 3,
465808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 } } },
466808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_sync", .ret_type = 1, .nargs = 3,
467808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMSFlags, 2 } } },
468808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_unlock", .ret_type = 1, .nargs = 2,
469808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
470808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_unmap", .ret_type = 1, .nargs = 2,
471808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
472808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_exec", .ret_type = 1, .nargs = 5,
473808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 },
474808d9805SEd Schouten 	            { IntArray, 3 }, { Int, 4 } } },
475808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_exit", .ret_type = 1, .nargs = 1,
476808d9805SEd Schouten 	  .args = { { Int, 0 } } },
477808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_fork", .ret_type = 1, .nargs = 0 },
478808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_raise", .ret_type = 1, .nargs = 1,
479808d9805SEd Schouten 	  .args = { { CloudABISignal, 0 } } },
480808d9805SEd Schouten 	{ .name = "cloudabi_sys_random_get", .ret_type = 1, .nargs = 2,
481808d9805SEd Schouten 	  .args = { { BinString | OUT, 0 }, { Int, 1 } } },
482808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_accept", .ret_type = 1, .nargs = 2,
483808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 } } },
484808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_bind", .ret_type = 1, .nargs = 3,
485808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } },
486808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_connect", .ret_type = 1, .nargs = 3,
487808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } },
488808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_listen", .ret_type = 1, .nargs = 2,
489808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 } } },
490808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_shutdown", .ret_type = 1, .nargs = 2,
491808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISDFlags, 1 } } },
492808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_stat_get", .ret_type = 1, .nargs = 3,
493808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 },
494808d9805SEd Schouten 	            { CloudABISSFlags, 2 } } },
495808d9805SEd Schouten 	{ .name = "cloudabi_sys_thread_exit", .ret_type = 1, .nargs = 2,
496808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } },
497808d9805SEd Schouten 	{ .name = "cloudabi_sys_thread_yield", .ret_type = 1, .nargs = 0 },
498808d9805SEd Schouten 
499ee3b0f6eSDiomidis Spinellis 	{ .name = 0 },
500bbeaf6c0SSean Eric Fagan };
5016c61b0f3SBryan Drewery static STAILQ_HEAD(, syscall) syscalls;
502bbeaf6c0SSean Eric Fagan 
503081e5c48SPav Lucistnik /* Xlat idea taken from strace */
504081e5c48SPav Lucistnik struct xlat {
505081e5c48SPav Lucistnik 	int val;
5065d2d083cSXin LI 	const char *str;
507081e5c48SPav Lucistnik };
508081e5c48SPav Lucistnik 
509081e5c48SPav Lucistnik #define	X(a)	{ a, #a },
510081e5c48SPav Lucistnik #define	XEND	{ 0, NULL }
511081e5c48SPav Lucistnik 
512081e5c48SPav Lucistnik static struct xlat kevent_filters[] = {
513081e5c48SPav Lucistnik 	X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE)
514081e5c48SPav Lucistnik 	X(EVFILT_PROC) X(EVFILT_SIGNAL) X(EVFILT_TIMER)
515d98d7ba0SJohn Baldwin 	X(EVFILT_PROCDESC) X(EVFILT_FS) X(EVFILT_LIO) X(EVFILT_USER)
516d98d7ba0SJohn Baldwin 	X(EVFILT_SENDFILE) XEND
517081e5c48SPav Lucistnik };
518081e5c48SPav Lucistnik 
519081e5c48SPav Lucistnik static struct xlat kevent_flags[] = {
520081e5c48SPav Lucistnik 	X(EV_ADD) X(EV_DELETE) X(EV_ENABLE) X(EV_DISABLE) X(EV_ONESHOT)
521d98d7ba0SJohn Baldwin 	X(EV_CLEAR) X(EV_RECEIPT) X(EV_DISPATCH) X(EV_FORCEONESHOT)
522d98d7ba0SJohn Baldwin 	X(EV_DROP) X(EV_FLAG1) X(EV_ERROR) X(EV_EOF) XEND
523081e5c48SPav Lucistnik };
524081e5c48SPav Lucistnik 
525c915ff03SJohn Baldwin static struct xlat kevent_user_ffctrl[] = {
526c915ff03SJohn Baldwin 	X(NOTE_FFNOP) X(NOTE_FFAND) X(NOTE_FFOR) X(NOTE_FFCOPY)
527c915ff03SJohn Baldwin 	XEND
528c915ff03SJohn Baldwin };
529c915ff03SJohn Baldwin 
530c915ff03SJohn Baldwin static struct xlat kevent_rdwr_fflags[] = {
531c915ff03SJohn Baldwin 	X(NOTE_LOWAT) X(NOTE_FILE_POLL) XEND
532c915ff03SJohn Baldwin };
533c915ff03SJohn Baldwin 
534c915ff03SJohn Baldwin static struct xlat kevent_vnode_fflags[] = {
535c915ff03SJohn Baldwin 	X(NOTE_DELETE) X(NOTE_WRITE) X(NOTE_EXTEND) X(NOTE_ATTRIB)
536c915ff03SJohn Baldwin 	X(NOTE_LINK) X(NOTE_RENAME) X(NOTE_REVOKE) XEND
537c915ff03SJohn Baldwin };
538c915ff03SJohn Baldwin 
539c915ff03SJohn Baldwin static struct xlat kevent_proc_fflags[] = {
540c915ff03SJohn Baldwin 	X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_TRACK) X(NOTE_TRACKERR)
541c915ff03SJohn Baldwin 	X(NOTE_CHILD) XEND
542c915ff03SJohn Baldwin };
543c915ff03SJohn Baldwin 
544c915ff03SJohn Baldwin static struct xlat kevent_timer_fflags[] = {
545c915ff03SJohn Baldwin 	X(NOTE_SECONDS) X(NOTE_MSECONDS) X(NOTE_USECONDS) X(NOTE_NSECONDS)
546c915ff03SJohn Baldwin 	XEND
547c915ff03SJohn Baldwin };
548c915ff03SJohn Baldwin 
549a02c83afSEd Schouten static struct xlat poll_flags[] = {
550081e5c48SPav Lucistnik 	X(POLLSTANDARD) X(POLLIN) X(POLLPRI) X(POLLOUT) X(POLLERR)
551081e5c48SPav Lucistnik 	X(POLLHUP) X(POLLNVAL) X(POLLRDNORM) X(POLLRDBAND)
552081e5c48SPav Lucistnik 	X(POLLWRBAND) X(POLLINIGNEOF) XEND
553081e5c48SPav Lucistnik };
554081e5c48SPav Lucistnik 
555081e5c48SPav Lucistnik static struct xlat sigaction_flags[] = {
556081e5c48SPav Lucistnik 	X(SA_ONSTACK) X(SA_RESTART) X(SA_RESETHAND) X(SA_NOCLDSTOP)
557081e5c48SPav Lucistnik 	X(SA_NODEFER) X(SA_NOCLDWAIT) X(SA_SIGINFO) XEND
558081e5c48SPav Lucistnik };
559081e5c48SPav Lucistnik 
560081e5c48SPav Lucistnik static struct xlat pathconf_arg[] = {
561081e5c48SPav Lucistnik 	X(_PC_LINK_MAX)  X(_PC_MAX_CANON)  X(_PC_MAX_INPUT)
562081e5c48SPav Lucistnik 	X(_PC_NAME_MAX) X(_PC_PATH_MAX) X(_PC_PIPE_BUF)
563081e5c48SPav Lucistnik 	X(_PC_CHOWN_RESTRICTED) X(_PC_NO_TRUNC) X(_PC_VDISABLE)
564081e5c48SPav Lucistnik 	X(_PC_ASYNC_IO) X(_PC_PRIO_IO) X(_PC_SYNC_IO)
565081e5c48SPav Lucistnik 	X(_PC_ALLOC_SIZE_MIN) X(_PC_FILESIZEBITS)
566081e5c48SPav Lucistnik 	X(_PC_REC_INCR_XFER_SIZE) X(_PC_REC_MAX_XFER_SIZE)
567081e5c48SPav Lucistnik 	X(_PC_REC_MIN_XFER_SIZE) X(_PC_REC_XFER_ALIGN)
568081e5c48SPav Lucistnik 	X(_PC_SYMLINK_MAX) X(_PC_ACL_EXTENDED) X(_PC_ACL_PATH_MAX)
569081e5c48SPav Lucistnik 	X(_PC_CAP_PRESENT) X(_PC_INF_PRESENT) X(_PC_MAC_PRESENT)
570d98d7ba0SJohn Baldwin 	X(_PC_ACL_NFS4) X(_PC_MIN_HOLE_SIZE) XEND
571081e5c48SPav Lucistnik };
572081e5c48SPav Lucistnik 
5737d897327SJohn Baldwin static struct xlat at_flags[] = {
5747d897327SJohn Baldwin 	X(AT_EACCESS) X(AT_SYMLINK_NOFOLLOW) X(AT_SYMLINK_FOLLOW)
5757d897327SJohn Baldwin 	X(AT_REMOVEDIR) XEND
5767d897327SJohn Baldwin };
5777d897327SJohn Baldwin 
578b289a8d7SJohn Baldwin static struct xlat sysarch_ops[] = {
579b289a8d7SJohn Baldwin #if defined(__i386__) || defined(__amd64__)
580b289a8d7SJohn Baldwin 	X(I386_GET_LDT) X(I386_SET_LDT) X(I386_GET_IOPERM) X(I386_SET_IOPERM)
581b289a8d7SJohn Baldwin 	X(I386_VM86) X(I386_GET_FSBASE) X(I386_SET_FSBASE) X(I386_GET_GSBASE)
582b289a8d7SJohn Baldwin 	X(I386_SET_GSBASE) X(I386_GET_XFPUSTATE) X(AMD64_GET_FSBASE)
583b289a8d7SJohn Baldwin 	X(AMD64_SET_FSBASE) X(AMD64_GET_GSBASE) X(AMD64_SET_GSBASE)
584b289a8d7SJohn Baldwin 	X(AMD64_GET_XFPUSTATE)
585b289a8d7SJohn Baldwin #endif
586b289a8d7SJohn Baldwin 	XEND
587b289a8d7SJohn Baldwin };
588fb7eabb0SJohn Baldwin 
589fb7eabb0SJohn Baldwin static struct xlat linux_socketcall_ops[] = {
590fb7eabb0SJohn Baldwin 	X(LINUX_SOCKET) X(LINUX_BIND) X(LINUX_CONNECT) X(LINUX_LISTEN)
591fb7eabb0SJohn Baldwin 	X(LINUX_ACCEPT) X(LINUX_GETSOCKNAME) X(LINUX_GETPEERNAME)
592fb7eabb0SJohn Baldwin 	X(LINUX_SOCKETPAIR) X(LINUX_SEND) X(LINUX_RECV) X(LINUX_SENDTO)
593fb7eabb0SJohn Baldwin 	X(LINUX_RECVFROM) X(LINUX_SHUTDOWN) X(LINUX_SETSOCKOPT)
594fb7eabb0SJohn Baldwin 	X(LINUX_GETSOCKOPT) X(LINUX_SENDMSG) X(LINUX_RECVMSG)
595fb7eabb0SJohn Baldwin 	XEND
596fb7eabb0SJohn Baldwin };
597fb7eabb0SJohn Baldwin 
598081e5c48SPav Lucistnik #undef X
599808d9805SEd Schouten #define	X(a)	{ CLOUDABI_##a, #a },
600808d9805SEd Schouten 
601808d9805SEd Schouten static struct xlat cloudabi_advice[] = {
602808d9805SEd Schouten 	X(ADVICE_DONTNEED) X(ADVICE_NOREUSE) X(ADVICE_NORMAL)
603808d9805SEd Schouten 	X(ADVICE_RANDOM) X(ADVICE_SEQUENTIAL) X(ADVICE_WILLNEED)
604808d9805SEd Schouten 	XEND
605808d9805SEd Schouten };
606808d9805SEd Schouten 
607808d9805SEd Schouten static struct xlat cloudabi_clockid[] = {
608808d9805SEd Schouten 	X(CLOCK_MONOTONIC) X(CLOCK_PROCESS_CPUTIME_ID)
609808d9805SEd Schouten 	X(CLOCK_REALTIME) X(CLOCK_THREAD_CPUTIME_ID)
610808d9805SEd Schouten 	XEND
611808d9805SEd Schouten };
612808d9805SEd Schouten 
613808d9805SEd Schouten static struct xlat cloudabi_errno[] = {
614808d9805SEd Schouten 	X(E2BIG) X(EACCES) X(EADDRINUSE) X(EADDRNOTAVAIL)
615808d9805SEd Schouten 	X(EAFNOSUPPORT) X(EAGAIN) X(EALREADY) X(EBADF) X(EBADMSG)
616808d9805SEd Schouten 	X(EBUSY) X(ECANCELED) X(ECHILD) X(ECONNABORTED) X(ECONNREFUSED)
617808d9805SEd Schouten 	X(ECONNRESET) X(EDEADLK) X(EDESTADDRREQ) X(EDOM) X(EDQUOT)
618808d9805SEd Schouten 	X(EEXIST) X(EFAULT) X(EFBIG) X(EHOSTUNREACH) X(EIDRM) X(EILSEQ)
619808d9805SEd Schouten 	X(EINPROGRESS) X(EINTR) X(EINVAL) X(EIO) X(EISCONN) X(EISDIR)
620808d9805SEd Schouten 	X(ELOOP) X(EMFILE) X(EMLINK) X(EMSGSIZE) X(EMULTIHOP)
621808d9805SEd Schouten 	X(ENAMETOOLONG) X(ENETDOWN) X(ENETRESET) X(ENETUNREACH)
622808d9805SEd Schouten 	X(ENFILE) X(ENOBUFS) X(ENODEV) X(ENOENT) X(ENOEXEC) X(ENOLCK)
623808d9805SEd Schouten 	X(ENOLINK) X(ENOMEM) X(ENOMSG) X(ENOPROTOOPT) X(ENOSPC)
624808d9805SEd Schouten 	X(ENOSYS) X(ENOTCONN) X(ENOTDIR) X(ENOTEMPTY) X(ENOTRECOVERABLE)
625808d9805SEd Schouten 	X(ENOTSOCK) X(ENOTSUP) X(ENOTTY) X(ENXIO) X(EOVERFLOW)
626808d9805SEd Schouten 	X(EOWNERDEAD) X(EPERM) X(EPIPE) X(EPROTO) X(EPROTONOSUPPORT)
627808d9805SEd Schouten 	X(EPROTOTYPE) X(ERANGE) X(EROFS) X(ESPIPE) X(ESRCH) X(ESTALE)
628808d9805SEd Schouten 	X(ETIMEDOUT) X(ETXTBSY) X(EXDEV) X(ENOTCAPABLE)
629808d9805SEd Schouten 	XEND
630808d9805SEd Schouten };
631808d9805SEd Schouten 
632808d9805SEd Schouten static struct xlat cloudabi_fdflags[] = {
633808d9805SEd Schouten 	X(FDFLAG_APPEND) X(FDFLAG_DSYNC) X(FDFLAG_NONBLOCK)
634808d9805SEd Schouten 	X(FDFLAG_RSYNC) X(FDFLAG_SYNC)
635808d9805SEd Schouten 	XEND
636808d9805SEd Schouten };
637808d9805SEd Schouten 
638808d9805SEd Schouten static struct xlat cloudabi_fdsflags[] = {
639808d9805SEd Schouten 	X(FDSTAT_FLAGS) X(FDSTAT_RIGHTS)
640808d9805SEd Schouten 	XEND
641808d9805SEd Schouten };
642808d9805SEd Schouten 
643808d9805SEd Schouten static struct xlat cloudabi_filetype[] = {
644808d9805SEd Schouten 	X(FILETYPE_UNKNOWN) X(FILETYPE_BLOCK_DEVICE)
645808d9805SEd Schouten 	X(FILETYPE_CHARACTER_DEVICE) X(FILETYPE_DIRECTORY)
646808d9805SEd Schouten 	X(FILETYPE_FIFO) X(FILETYPE_POLL) X(FILETYPE_PROCESS)
647808d9805SEd Schouten 	X(FILETYPE_REGULAR_FILE) X(FILETYPE_SHARED_MEMORY)
648808d9805SEd Schouten 	X(FILETYPE_SOCKET_DGRAM) X(FILETYPE_SOCKET_SEQPACKET)
649808d9805SEd Schouten 	X(FILETYPE_SOCKET_STREAM) X(FILETYPE_SYMBOLIC_LINK)
650808d9805SEd Schouten 	XEND
651808d9805SEd Schouten };
652808d9805SEd Schouten 
653808d9805SEd Schouten static struct xlat cloudabi_fsflags[] = {
654808d9805SEd Schouten 	X(FILESTAT_ATIM) X(FILESTAT_ATIM_NOW) X(FILESTAT_MTIM)
655808d9805SEd Schouten 	X(FILESTAT_MTIM_NOW) X(FILESTAT_SIZE)
656808d9805SEd Schouten 	XEND
657808d9805SEd Schouten };
658808d9805SEd Schouten 
659808d9805SEd Schouten static struct xlat cloudabi_mflags[] = {
660808d9805SEd Schouten 	X(MAP_ANON) X(MAP_FIXED) X(MAP_PRIVATE) X(MAP_SHARED)
661808d9805SEd Schouten 	XEND
662808d9805SEd Schouten };
663808d9805SEd Schouten 
664808d9805SEd Schouten static struct xlat cloudabi_mprot[] = {
665808d9805SEd Schouten 	X(PROT_EXEC) X(PROT_WRITE) X(PROT_READ)
666808d9805SEd Schouten 	XEND
667808d9805SEd Schouten };
668808d9805SEd Schouten 
669808d9805SEd Schouten static struct xlat cloudabi_msflags[] = {
670808d9805SEd Schouten 	X(MS_ASYNC) X(MS_INVALIDATE) X(MS_SYNC)
671808d9805SEd Schouten 	XEND
672808d9805SEd Schouten };
673808d9805SEd Schouten 
674808d9805SEd Schouten static struct xlat cloudabi_oflags[] = {
675808d9805SEd Schouten 	X(O_CREAT) X(O_DIRECTORY) X(O_EXCL) X(O_TRUNC)
676808d9805SEd Schouten 	XEND
677808d9805SEd Schouten };
678808d9805SEd Schouten 
679808d9805SEd Schouten static struct xlat cloudabi_sa_family[] = {
680808d9805SEd Schouten 	X(AF_UNSPEC) X(AF_INET) X(AF_INET6) X(AF_UNIX)
681808d9805SEd Schouten 	XEND
682808d9805SEd Schouten };
683808d9805SEd Schouten 
684808d9805SEd Schouten static struct xlat cloudabi_sdflags[] = {
685808d9805SEd Schouten 	X(SHUT_RD) X(SHUT_WR)
686808d9805SEd Schouten 	XEND
687808d9805SEd Schouten };
688808d9805SEd Schouten 
689808d9805SEd Schouten static struct xlat cloudabi_signal[] = {
690808d9805SEd Schouten 	X(SIGABRT) X(SIGALRM) X(SIGBUS) X(SIGCHLD) X(SIGCONT) X(SIGFPE)
691808d9805SEd Schouten 	X(SIGHUP) X(SIGILL) X(SIGINT) X(SIGKILL) X(SIGPIPE) X(SIGQUIT)
692808d9805SEd Schouten 	X(SIGSEGV) X(SIGSTOP) X(SIGSYS) X(SIGTERM) X(SIGTRAP) X(SIGTSTP)
693808d9805SEd Schouten 	X(SIGTTIN) X(SIGTTOU) X(SIGURG) X(SIGUSR1) X(SIGUSR2)
694808d9805SEd Schouten 	X(SIGVTALRM) X(SIGXCPU) X(SIGXFSZ)
695808d9805SEd Schouten 	XEND
696808d9805SEd Schouten };
697808d9805SEd Schouten 
698808d9805SEd Schouten static struct xlat cloudabi_ssflags[] = {
699808d9805SEd Schouten 	X(SOCKSTAT_CLEAR_ERROR)
700808d9805SEd Schouten 	XEND
701808d9805SEd Schouten };
702808d9805SEd Schouten 
703808d9805SEd Schouten static struct xlat cloudabi_ssstate[] = {
7041f3bbfd8SEd Schouten 	X(SOCKSTATE_ACCEPTCONN)
705808d9805SEd Schouten 	XEND
706808d9805SEd Schouten };
707808d9805SEd Schouten 
708808d9805SEd Schouten static struct xlat cloudabi_ulflags[] = {
709808d9805SEd Schouten 	X(UNLINK_REMOVEDIR)
710808d9805SEd Schouten 	XEND
711808d9805SEd Schouten };
712808d9805SEd Schouten 
713808d9805SEd Schouten static struct xlat cloudabi_whence[] = {
714808d9805SEd Schouten 	X(WHENCE_CUR) X(WHENCE_END) X(WHENCE_SET)
715808d9805SEd Schouten 	XEND
716808d9805SEd Schouten };
717808d9805SEd Schouten 
718808d9805SEd Schouten #undef X
719081e5c48SPav Lucistnik #undef XEND
720081e5c48SPav Lucistnik 
721d8984f48SDag-Erling Smørgrav /*
722d8984f48SDag-Erling Smørgrav  * Searches an xlat array for a value, and returns it if found.  Otherwise
723d8984f48SDag-Erling Smørgrav  * return a string representation.
724d8984f48SDag-Erling Smørgrav  */
725d8984f48SDag-Erling Smørgrav static const char *
726d8984f48SDag-Erling Smørgrav lookup(struct xlat *xlat, int val, int base)
727081e5c48SPav Lucistnik {
728081e5c48SPav Lucistnik 	static char tmp[16];
729d8984f48SDag-Erling Smørgrav 
730081e5c48SPav Lucistnik 	for (; xlat->str != NULL; xlat++)
731081e5c48SPav Lucistnik 		if (xlat->val == val)
732d8984f48SDag-Erling Smørgrav 			return (xlat->str);
733081e5c48SPav Lucistnik 	switch (base) {
734081e5c48SPav Lucistnik 		case 8:
735081e5c48SPav Lucistnik 			sprintf(tmp, "0%o", val);
736081e5c48SPav Lucistnik 			break;
737081e5c48SPav Lucistnik 		case 16:
738081e5c48SPav Lucistnik 			sprintf(tmp, "0x%x", val);
739081e5c48SPav Lucistnik 			break;
740081e5c48SPav Lucistnik 		case 10:
741081e5c48SPav Lucistnik 			sprintf(tmp, "%u", val);
742081e5c48SPav Lucistnik 			break;
743081e5c48SPav Lucistnik 		default:
744081e5c48SPav Lucistnik 			errx(1,"Unknown lookup base");
745081e5c48SPav Lucistnik 			break;
746081e5c48SPav Lucistnik 	}
747d8984f48SDag-Erling Smørgrav 	return (tmp);
748081e5c48SPav Lucistnik }
749081e5c48SPav Lucistnik 
7505d2d083cSXin LI static const char *
7515d2d083cSXin LI xlookup(struct xlat *xlat, int val)
752081e5c48SPav Lucistnik {
753d8984f48SDag-Erling Smørgrav 
754d8984f48SDag-Erling Smørgrav 	return (lookup(xlat, val, 16));
755081e5c48SPav Lucistnik }
756081e5c48SPav Lucistnik 
7574e3da534SJohn Baldwin /*
7584e3da534SJohn Baldwin  * Searches an xlat array containing bitfield values.  Remaining bits
7594e3da534SJohn Baldwin  * set after removing the known ones are printed at the end:
7604e3da534SJohn Baldwin  * IN|0x400.
7614e3da534SJohn Baldwin  */
762d8984f48SDag-Erling Smørgrav static char *
763d8984f48SDag-Erling Smørgrav xlookup_bits(struct xlat *xlat, int val)
764081e5c48SPav Lucistnik {
76594355cfdSAndrey Zonov 	int len, rem;
766081e5c48SPav Lucistnik 	static char str[512];
767081e5c48SPav Lucistnik 
76894355cfdSAndrey Zonov 	len = 0;
76994355cfdSAndrey Zonov 	rem = val;
770d8984f48SDag-Erling Smørgrav 	for (; xlat->str != NULL; xlat++) {
771d8984f48SDag-Erling Smørgrav 		if ((xlat->val & rem) == xlat->val) {
7724e3da534SJohn Baldwin 			/*
7734e3da534SJohn Baldwin 			 * Don't print the "all-bits-zero" string unless all
7744e3da534SJohn Baldwin 			 * bits are really zero.
7754e3da534SJohn Baldwin 			 */
776081e5c48SPav Lucistnik 			if (xlat->val == 0 && val != 0)
777081e5c48SPav Lucistnik 				continue;
778081e5c48SPav Lucistnik 			len += sprintf(str + len, "%s|", xlat->str);
779081e5c48SPav Lucistnik 			rem &= ~(xlat->val);
780081e5c48SPav Lucistnik 		}
781081e5c48SPav Lucistnik 	}
7824e3da534SJohn Baldwin 
7834e3da534SJohn Baldwin 	/*
7844e3da534SJohn Baldwin 	 * If we have leftover bits or didn't match anything, print
7854e3da534SJohn Baldwin 	 * the remainder.
7864e3da534SJohn Baldwin 	 */
787081e5c48SPav Lucistnik 	if (rem || len == 0)
788081e5c48SPav Lucistnik 		len += sprintf(str + len, "0x%x", rem);
789081e5c48SPav Lucistnik 	if (len && str[len - 1] == '|')
790081e5c48SPav Lucistnik 		len--;
791081e5c48SPav Lucistnik 	str[len] = 0;
792d8984f48SDag-Erling Smørgrav 	return (str);
793081e5c48SPav Lucistnik }
794081e5c48SPav Lucistnik 
7959289f547SJohn Baldwin static void
7969289f547SJohn Baldwin print_integer_arg(const char *(*decoder)(int), FILE *fp, int value)
7979289f547SJohn Baldwin {
7989289f547SJohn Baldwin 	const char *str;
7999289f547SJohn Baldwin 
8009289f547SJohn Baldwin 	str = decoder(value);
8019289f547SJohn Baldwin 	if (str != NULL)
8029289f547SJohn Baldwin 		fputs(str, fp);
8039289f547SJohn Baldwin 	else
8049289f547SJohn Baldwin 		fprintf(fp, "%d", value);
8059289f547SJohn Baldwin }
8069289f547SJohn Baldwin 
8079289f547SJohn Baldwin static void
8089289f547SJohn Baldwin print_mask_arg(bool (*decoder)(FILE *, int, int *), FILE *fp, int value)
8099289f547SJohn Baldwin {
8109289f547SJohn Baldwin 	int rem;
8119289f547SJohn Baldwin 
8129289f547SJohn Baldwin 	if (!decoder(fp, value, &rem))
8139289f547SJohn Baldwin 		fprintf(fp, "0x%x", rem);
8149289f547SJohn Baldwin 	else if (rem != 0)
8159289f547SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
8169289f547SJohn Baldwin }
8179289f547SJohn Baldwin 
818bed418c8SJohn Baldwin static void
819bed418c8SJohn Baldwin print_mask_arg32(bool (*decoder)(FILE *, uint32_t, uint32_t *), FILE *fp,
820bed418c8SJohn Baldwin     uint32_t value)
821bed418c8SJohn Baldwin {
822bed418c8SJohn Baldwin 	uint32_t rem;
823bed418c8SJohn Baldwin 
824bed418c8SJohn Baldwin 	if (!decoder(fp, value, &rem))
825bed418c8SJohn Baldwin 		fprintf(fp, "0x%x", rem);
826bed418c8SJohn Baldwin 	else if (rem != 0)
827bed418c8SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
828bed418c8SJohn Baldwin }
829bed418c8SJohn Baldwin 
830c05cc0d6SJohn Baldwin #ifndef __LP64__
831c05cc0d6SJohn Baldwin /*
832c05cc0d6SJohn Baldwin  * Add argument padding to subsequent system calls afater a Quad
833c05cc0d6SJohn Baldwin  * syscall arguments as needed.  This used to be done by hand in the
834c05cc0d6SJohn Baldwin  * decoded_syscalls table which was ugly and error prone.  It is
835c05cc0d6SJohn Baldwin  * simpler to do the fixup of offsets at initalization time than when
836c05cc0d6SJohn Baldwin  * decoding arguments.
837c05cc0d6SJohn Baldwin  */
838c05cc0d6SJohn Baldwin static void
839c05cc0d6SJohn Baldwin quad_fixup(struct syscall *sc)
840c05cc0d6SJohn Baldwin {
841c05cc0d6SJohn Baldwin 	int offset, prev;
842c05cc0d6SJohn Baldwin 	u_int i;
843c05cc0d6SJohn Baldwin 
844c05cc0d6SJohn Baldwin 	offset = 0;
845c05cc0d6SJohn Baldwin 	prev = -1;
846c05cc0d6SJohn Baldwin 	for (i = 0; i < sc->nargs; i++) {
847c05cc0d6SJohn Baldwin 		/* This arg type is a dummy that doesn't use offset. */
848c05cc0d6SJohn Baldwin 		if ((sc->args[i].type & ARG_MASK) == PipeFds)
849c05cc0d6SJohn Baldwin 			continue;
850c05cc0d6SJohn Baldwin 
851c05cc0d6SJohn Baldwin 		assert(prev < sc->args[i].offset);
852c05cc0d6SJohn Baldwin 		prev = sc->args[i].offset;
853c05cc0d6SJohn Baldwin 		sc->args[i].offset += offset;
854c05cc0d6SJohn Baldwin 		switch (sc->args[i].type & ARG_MASK) {
855c05cc0d6SJohn Baldwin 		case Quad:
856c05cc0d6SJohn Baldwin 		case QuadHex:
857c05cc0d6SJohn Baldwin #ifdef __powerpc__
858c05cc0d6SJohn Baldwin 			/*
859c05cc0d6SJohn Baldwin 			 * 64-bit arguments on 32-bit powerpc must be
860c05cc0d6SJohn Baldwin 			 * 64-bit aligned.  If the current offset is
861c05cc0d6SJohn Baldwin 			 * not aligned, the calling convention inserts
862c05cc0d6SJohn Baldwin 			 * a 32-bit pad argument that should be skipped.
863c05cc0d6SJohn Baldwin 			 */
864c05cc0d6SJohn Baldwin 			if (sc->args[i].offset % 2 == 1) {
865c05cc0d6SJohn Baldwin 				sc->args[i].offset++;
866c05cc0d6SJohn Baldwin 				offset++;
867c05cc0d6SJohn Baldwin 			}
868c05cc0d6SJohn Baldwin #endif
869c05cc0d6SJohn Baldwin 			offset++;
870c05cc0d6SJohn Baldwin 		default:
871c05cc0d6SJohn Baldwin 			break;
872c05cc0d6SJohn Baldwin 		}
873c05cc0d6SJohn Baldwin 	}
874c05cc0d6SJohn Baldwin }
875c05cc0d6SJohn Baldwin #endif
876c05cc0d6SJohn Baldwin 
8776c61b0f3SBryan Drewery void
8786c61b0f3SBryan Drewery init_syscalls(void)
8796c61b0f3SBryan Drewery {
8806c61b0f3SBryan Drewery 	struct syscall *sc;
8816c61b0f3SBryan Drewery 
8826c61b0f3SBryan Drewery 	STAILQ_INIT(&syscalls);
883c05cc0d6SJohn Baldwin 	for (sc = decoded_syscalls; sc->name != NULL; sc++) {
884c05cc0d6SJohn Baldwin #ifndef __LP64__
885c05cc0d6SJohn Baldwin 		quad_fixup(sc);
886c05cc0d6SJohn Baldwin #endif
8876c61b0f3SBryan Drewery 		STAILQ_INSERT_HEAD(&syscalls, sc, entries);
8886c61b0f3SBryan Drewery 	}
889c05cc0d6SJohn Baldwin }
8901175b23fSJohn Baldwin 
8911175b23fSJohn Baldwin static struct syscall *
8921175b23fSJohn Baldwin find_syscall(struct procabi *abi, u_int number)
8931175b23fSJohn Baldwin {
8941175b23fSJohn Baldwin 	struct extra_syscall *es;
8951175b23fSJohn Baldwin 
8961175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls))
8971175b23fSJohn Baldwin 		return (abi->syscalls[number]);
8981175b23fSJohn Baldwin 	STAILQ_FOREACH(es, &abi->extra_syscalls, entries) {
8991175b23fSJohn Baldwin 		if (es->number == number)
9001175b23fSJohn Baldwin 			return (es->sc);
9011175b23fSJohn Baldwin 	}
9021175b23fSJohn Baldwin 	return (NULL);
9031175b23fSJohn Baldwin }
9041175b23fSJohn Baldwin 
9051175b23fSJohn Baldwin static void
9061175b23fSJohn Baldwin add_syscall(struct procabi *abi, u_int number, struct syscall *sc)
9071175b23fSJohn Baldwin {
9081175b23fSJohn Baldwin 	struct extra_syscall *es;
9091175b23fSJohn Baldwin 
9101175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls)) {
9111175b23fSJohn Baldwin 		assert(abi->syscalls[number] == NULL);
9121175b23fSJohn Baldwin 		abi->syscalls[number] = sc;
9131175b23fSJohn Baldwin 	} else {
9141175b23fSJohn Baldwin 		es = malloc(sizeof(*es));
9151175b23fSJohn Baldwin 		es->sc = sc;
9161175b23fSJohn Baldwin 		es->number = number;
9171175b23fSJohn Baldwin 		STAILQ_INSERT_TAIL(&abi->extra_syscalls, es, entries);
9181175b23fSJohn Baldwin 	}
9191175b23fSJohn Baldwin }
9201175b23fSJohn Baldwin 
921bbeaf6c0SSean Eric Fagan /*
922bbeaf6c0SSean Eric Fagan  * If/when the list gets big, it might be desirable to do it
923bbeaf6c0SSean Eric Fagan  * as a hash table or binary search.
924bbeaf6c0SSean Eric Fagan  */
925bbeaf6c0SSean Eric Fagan struct syscall *
9261175b23fSJohn Baldwin get_syscall(struct threadinfo *t, u_int number, u_int nargs)
927d8984f48SDag-Erling Smørgrav {
92894355cfdSAndrey Zonov 	struct syscall *sc;
9291175b23fSJohn Baldwin 	const char *name;
9301175b23fSJohn Baldwin 	char *new_name;
9311175b23fSJohn Baldwin 	u_int i;
932bbeaf6c0SSean Eric Fagan 
9331175b23fSJohn Baldwin 	sc = find_syscall(t->proc->abi, number);
9341175b23fSJohn Baldwin 	if (sc != NULL)
935d8984f48SDag-Erling Smørgrav 		return (sc);
9366c61b0f3SBryan Drewery 
9371175b23fSJohn Baldwin 	name = sysdecode_syscallname(t->proc->abi->abi, number);
9381175b23fSJohn Baldwin 	if (name == NULL) {
9391175b23fSJohn Baldwin 		asprintf(&new_name, "#%d", number);
9401175b23fSJohn Baldwin 		name = new_name;
9411175b23fSJohn Baldwin 	} else
9421175b23fSJohn Baldwin 		new_name = NULL;
9431175b23fSJohn Baldwin 	STAILQ_FOREACH(sc, &syscalls, entries) {
9441175b23fSJohn Baldwin 		if (strcmp(name, sc->name) == 0) {
9451175b23fSJohn Baldwin 			add_syscall(t->proc->abi, number, sc);
9461175b23fSJohn Baldwin 			free(new_name);
9471175b23fSJohn Baldwin 			return (sc);
9481175b23fSJohn Baldwin 		}
9491175b23fSJohn Baldwin 	}
9501175b23fSJohn Baldwin 
9516c61b0f3SBryan Drewery 	/* It is unknown.  Add it into the list. */
9526c61b0f3SBryan Drewery #if DEBUG
9536c61b0f3SBryan Drewery 	fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
9546c61b0f3SBryan Drewery 	    nargs);
9556c61b0f3SBryan Drewery #endif
9566c61b0f3SBryan Drewery 
9576c61b0f3SBryan Drewery 	sc = calloc(1, sizeof(struct syscall));
9581175b23fSJohn Baldwin 	sc->name = name;
9591175b23fSJohn Baldwin 	if (new_name != NULL)
9601175b23fSJohn Baldwin 		sc->unknown = true;
9616c61b0f3SBryan Drewery 	sc->ret_type = 1;
9626c61b0f3SBryan Drewery 	sc->nargs = nargs;
9636c61b0f3SBryan Drewery 	for (i = 0; i < nargs; i++) {
9646c61b0f3SBryan Drewery 		sc->args[i].offset = i;
9656c61b0f3SBryan Drewery 		/* Treat all unknown arguments as LongHex. */
9666c61b0f3SBryan Drewery 		sc->args[i].type = LongHex;
967bbeaf6c0SSean Eric Fagan 	}
9686c61b0f3SBryan Drewery 	STAILQ_INSERT_HEAD(&syscalls, sc, entries);
9691175b23fSJohn Baldwin 	add_syscall(t->proc->abi, number, sc);
9706c61b0f3SBryan Drewery 
9716c61b0f3SBryan Drewery 	return (sc);
972bbeaf6c0SSean Eric Fagan }
973bbeaf6c0SSean Eric Fagan 
974bbeaf6c0SSean Eric Fagan /*
9759ddd1412SDag-Erling Smørgrav  * Copy a fixed amount of bytes from the process.
9769ddd1412SDag-Erling Smørgrav  */
9771be5d704SMark Murray static int
978be305c9cSAndrey Zonov get_struct(pid_t pid, void *offset, void *buf, int len)
979d8984f48SDag-Erling Smørgrav {
9805d2d083cSXin LI 	struct ptrace_io_desc iorequest;
9819ddd1412SDag-Erling Smørgrav 
9825d2d083cSXin LI 	iorequest.piod_op = PIOD_READ_D;
9835d2d083cSXin LI 	iorequest.piod_offs = offset;
9845d2d083cSXin LI 	iorequest.piod_addr = buf;
9855d2d083cSXin LI 	iorequest.piod_len = len;
9865d2d083cSXin LI 	if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0)
987d8984f48SDag-Erling Smørgrav 		return (-1);
988d8984f48SDag-Erling Smørgrav 	return (0);
9899ddd1412SDag-Erling Smørgrav }
9909ddd1412SDag-Erling Smørgrav 
9915d2d083cSXin LI #define	MAXSIZE		4096
992abb3f965SJohn Baldwin 
9939ddd1412SDag-Erling Smørgrav /*
994bbeaf6c0SSean Eric Fagan  * Copy a string from the process.  Note that it is
995bbeaf6c0SSean Eric Fagan  * expected to be a C string, but if max is set, it will
996bbeaf6c0SSean Eric Fagan  * only get that much.
997bbeaf6c0SSean Eric Fagan  */
9985d2d083cSXin LI static char *
999abb3f965SJohn Baldwin get_string(pid_t pid, void *addr, int max)
1000d8984f48SDag-Erling Smørgrav {
10015d2d083cSXin LI 	struct ptrace_io_desc iorequest;
1002abb3f965SJohn Baldwin 	char *buf, *nbuf;
1003abb3f965SJohn Baldwin 	size_t offset, size, totalsize;
1004bbeaf6c0SSean Eric Fagan 
1005abb3f965SJohn Baldwin 	offset = 0;
1006abb3f965SJohn Baldwin 	if (max)
1007abb3f965SJohn Baldwin 		size = max + 1;
1008abb3f965SJohn Baldwin 	else {
1009abb3f965SJohn Baldwin 		/* Read up to the end of the current page. */
1010abb3f965SJohn Baldwin 		size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE);
1011abb3f965SJohn Baldwin 		if (size > MAXSIZE)
1012abb3f965SJohn Baldwin 			size = MAXSIZE;
1013abb3f965SJohn Baldwin 	}
1014abb3f965SJohn Baldwin 	totalsize = size;
10155d2d083cSXin LI 	buf = malloc(totalsize);
10165d2d083cSXin LI 	if (buf == NULL)
1017d8984f48SDag-Erling Smørgrav 		return (NULL);
10185d2d083cSXin LI 	for (;;) {
10195d2d083cSXin LI 		iorequest.piod_op = PIOD_READ_D;
1020abb3f965SJohn Baldwin 		iorequest.piod_offs = (char *)addr + offset;
1021abb3f965SJohn Baldwin 		iorequest.piod_addr = buf + offset;
10225d2d083cSXin LI 		iorequest.piod_len = size;
10235d2d083cSXin LI 		if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) {
10245d2d083cSXin LI 			free(buf);
1025d8984f48SDag-Erling Smørgrav 			return (NULL);
1026bbeaf6c0SSean Eric Fagan 		}
1027abb3f965SJohn Baldwin 		if (memchr(buf + offset, '\0', size) != NULL)
1028abb3f965SJohn Baldwin 			return (buf);
1029abb3f965SJohn Baldwin 		offset += size;
1030abb3f965SJohn Baldwin 		if (totalsize < MAXSIZE && max == 0) {
1031abb3f965SJohn Baldwin 			size = MAXSIZE - totalsize;
1032abb3f965SJohn Baldwin 			if (size > PAGE_SIZE)
1033abb3f965SJohn Baldwin 				size = PAGE_SIZE;
1034abb3f965SJohn Baldwin 			nbuf = realloc(buf, totalsize + size);
1035abb3f965SJohn Baldwin 			if (nbuf == NULL) {
1036abb3f965SJohn Baldwin 				buf[totalsize - 1] = '\0';
10374e92419dSMarcel Moolenaar 				return (buf);
1038bbeaf6c0SSean Eric Fagan 			}
1039abb3f965SJohn Baldwin 			buf = nbuf;
1040abb3f965SJohn Baldwin 			totalsize += size;
1041d8984f48SDag-Erling Smørgrav 		} else {
1042cdfc719cSJaakko Heinonen 			buf[totalsize - 1] = '\0';
1043d8984f48SDag-Erling Smørgrav 			return (buf);
10445d2d083cSXin LI 		}
10455d2d083cSXin LI 	}
10465d2d083cSXin LI }
1047bbeaf6c0SSean Eric Fagan 
10489289f547SJohn Baldwin static const char *
104934763d1cSJohn Baldwin strsig2(int sig)
105034763d1cSJohn Baldwin {
10519289f547SJohn Baldwin 	static char tmp[32];
10529289f547SJohn Baldwin 	const char *signame;
105334763d1cSJohn Baldwin 
10549289f547SJohn Baldwin 	signame = sysdecode_signal(sig);
10559289f547SJohn Baldwin 	if (signame == NULL) {
1056f083f689SJohn Baldwin 		snprintf(tmp, sizeof(tmp), "%d", sig);
10579289f547SJohn Baldwin 		signame = tmp;
1058f083f689SJohn Baldwin 	}
10599289f547SJohn Baldwin 	return (signame);
106034763d1cSJohn Baldwin }
1061bbeaf6c0SSean Eric Fagan 
1062c915ff03SJohn Baldwin static void
1063c915ff03SJohn Baldwin print_kevent(FILE *fp, struct kevent *ke, int input)
1064c915ff03SJohn Baldwin {
1065c915ff03SJohn Baldwin 
1066c915ff03SJohn Baldwin 	switch (ke->filter) {
1067c915ff03SJohn Baldwin 	case EVFILT_READ:
1068c915ff03SJohn Baldwin 	case EVFILT_WRITE:
1069c915ff03SJohn Baldwin 	case EVFILT_VNODE:
1070c915ff03SJohn Baldwin 	case EVFILT_PROC:
1071c915ff03SJohn Baldwin 	case EVFILT_TIMER:
1072c915ff03SJohn Baldwin 	case EVFILT_PROCDESC:
1073c915ff03SJohn Baldwin 		fprintf(fp, "%ju", (uintmax_t)ke->ident);
1074c915ff03SJohn Baldwin 		break;
1075c915ff03SJohn Baldwin 	case EVFILT_SIGNAL:
1076c915ff03SJohn Baldwin 		fputs(strsig2(ke->ident), fp);
1077c915ff03SJohn Baldwin 		break;
1078c915ff03SJohn Baldwin 	default:
1079c915ff03SJohn Baldwin 		fprintf(fp, "%p", (void *)ke->ident);
1080c915ff03SJohn Baldwin 	}
1081c915ff03SJohn Baldwin 	fprintf(fp, ",%s,%s,", xlookup(kevent_filters, ke->filter),
1082c915ff03SJohn Baldwin 	    xlookup_bits(kevent_flags, ke->flags));
1083c915ff03SJohn Baldwin 	switch (ke->filter) {
1084c915ff03SJohn Baldwin 	case EVFILT_READ:
1085c915ff03SJohn Baldwin 	case EVFILT_WRITE:
1086c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_rdwr_fflags, ke->fflags), fp);
1087c915ff03SJohn Baldwin 		break;
1088c915ff03SJohn Baldwin 	case EVFILT_VNODE:
1089c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_vnode_fflags, ke->fflags), fp);
1090c915ff03SJohn Baldwin 		break;
1091c915ff03SJohn Baldwin 	case EVFILT_PROC:
1092c915ff03SJohn Baldwin 	case EVFILT_PROCDESC:
1093c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_proc_fflags, ke->fflags), fp);
1094c915ff03SJohn Baldwin 		break;
1095c915ff03SJohn Baldwin 	case EVFILT_TIMER:
1096c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_timer_fflags, ke->fflags), fp);
1097c915ff03SJohn Baldwin 		break;
1098c915ff03SJohn Baldwin 	case EVFILT_USER: {
1099c915ff03SJohn Baldwin 		int ctrl, data;
1100c915ff03SJohn Baldwin 
1101c915ff03SJohn Baldwin 		ctrl = ke->fflags & NOTE_FFCTRLMASK;
1102c915ff03SJohn Baldwin 		data = ke->fflags & NOTE_FFLAGSMASK;
1103c915ff03SJohn Baldwin 		if (input) {
1104c915ff03SJohn Baldwin 			fputs(xlookup(kevent_user_ffctrl, ctrl), fp);
1105c915ff03SJohn Baldwin 			if (ke->fflags & NOTE_TRIGGER)
1106c915ff03SJohn Baldwin 				fputs("|NOTE_TRIGGER", fp);
1107c915ff03SJohn Baldwin 			if (data != 0)
1108c915ff03SJohn Baldwin 				fprintf(fp, "|%#x", data);
1109c915ff03SJohn Baldwin 		} else {
1110c915ff03SJohn Baldwin 			fprintf(fp, "%#x", data);
1111c915ff03SJohn Baldwin 		}
1112c915ff03SJohn Baldwin 		break;
1113c915ff03SJohn Baldwin 	}
1114c915ff03SJohn Baldwin 	default:
1115c915ff03SJohn Baldwin 		fprintf(fp, "%#x", ke->fflags);
1116c915ff03SJohn Baldwin 	}
1117c915ff03SJohn Baldwin 	fprintf(fp, ",%p,%p", (void *)ke->data, (void *)ke->udata);
1118c915ff03SJohn Baldwin }
1119c915ff03SJohn Baldwin 
1120195aef99SBryan Drewery static void
1121195aef99SBryan Drewery print_utrace(FILE *fp, void *utrace_addr, size_t len)
1122195aef99SBryan Drewery {
1123195aef99SBryan Drewery 	unsigned char *utrace_buffer;
1124195aef99SBryan Drewery 
1125195aef99SBryan Drewery 	fprintf(fp, "{ ");
1126d6fb4894SJohn Baldwin 	if (sysdecode_utrace(fp, utrace_addr, len)) {
1127195aef99SBryan Drewery 		fprintf(fp, " }");
1128195aef99SBryan Drewery 		return;
1129195aef99SBryan Drewery 	}
1130195aef99SBryan Drewery 
1131195aef99SBryan Drewery 	utrace_buffer = utrace_addr;
1132195aef99SBryan Drewery 	fprintf(fp, "%zu:", len);
1133195aef99SBryan Drewery 	while (len--)
1134195aef99SBryan Drewery 		fprintf(fp, " %02x", *utrace_buffer++);
1135195aef99SBryan Drewery 	fprintf(fp, " }");
1136195aef99SBryan Drewery }
1137195aef99SBryan Drewery 
1138bbeaf6c0SSean Eric Fagan /*
1139bbeaf6c0SSean Eric Fagan  * Converts a syscall argument into a string.  Said string is
11404e3da534SJohn Baldwin  * allocated via malloc(), so needs to be free()'d.  sc is
1141bbeaf6c0SSean Eric Fagan  * a pointer to the syscall description (see above); args is
1142bbeaf6c0SSean Eric Fagan  * an array of all of the system call arguments.
1143bbeaf6c0SSean Eric Fagan  */
1144bbeaf6c0SSean Eric Fagan char *
11452b75c8adSJohn Baldwin print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
114694355cfdSAndrey Zonov     struct trussinfo *trussinfo)
1147d8984f48SDag-Erling Smørgrav {
1148f083f689SJohn Baldwin 	FILE *fp;
114994355cfdSAndrey Zonov 	char *tmp;
1150f083f689SJohn Baldwin 	size_t tmplen;
115194355cfdSAndrey Zonov 	pid_t pid;
1152d8984f48SDag-Erling Smørgrav 
1153f083f689SJohn Baldwin 	fp = open_memstream(&tmp, &tmplen);
11542b75c8adSJohn Baldwin 	pid = trussinfo->curthread->proc->pid;
1155bbeaf6c0SSean Eric Fagan 	switch (sc->type & ARG_MASK) {
1156bbeaf6c0SSean Eric Fagan 	case Hex:
1157f083f689SJohn Baldwin 		fprintf(fp, "0x%x", (int)args[sc->offset]);
1158bbeaf6c0SSean Eric Fagan 		break;
1159bbeaf6c0SSean Eric Fagan 	case Octal:
1160f083f689SJohn Baldwin 		fprintf(fp, "0%o", (int)args[sc->offset]);
1161bbeaf6c0SSean Eric Fagan 		break;
1162bbeaf6c0SSean Eric Fagan 	case Int:
1163f083f689SJohn Baldwin 		fprintf(fp, "%d", (int)args[sc->offset]);
1164bbeaf6c0SSean Eric Fagan 		break;
1165808d9805SEd Schouten 	case UInt:
1166808d9805SEd Schouten 		fprintf(fp, "%u", (unsigned int)args[sc->offset]);
1167808d9805SEd Schouten 		break;
1168fdb5bf37SJohn Baldwin 	case LongHex:
1169f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
1170fdb5bf37SJohn Baldwin 		break;
1171b289a8d7SJohn Baldwin 	case Long:
1172f083f689SJohn Baldwin 		fprintf(fp, "%ld", args[sc->offset]);
1173b289a8d7SJohn Baldwin 		break;
1174e261fb2aSJohn Baldwin 	case Sizet:
1175e261fb2aSJohn Baldwin 		fprintf(fp, "%zu", (size_t)args[sc->offset]);
1176e261fb2aSJohn Baldwin 		break;
1177d8984f48SDag-Erling Smørgrav 	case Name: {
1178081e5c48SPav Lucistnik 		/* NULL-terminated string. */
1179bbeaf6c0SSean Eric Fagan 		char *tmp2;
11804e3da534SJohn Baldwin 
11815d2d083cSXin LI 		tmp2 = get_string(pid, (void*)args[sc->offset], 0);
1182f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
1183bbeaf6c0SSean Eric Fagan 		free(tmp2);
1184bbeaf6c0SSean Eric Fagan 		break;
1185d8984f48SDag-Erling Smørgrav 	}
1186d8984f48SDag-Erling Smørgrav 	case BinString: {
11874e3da534SJohn Baldwin 		/*
11884e3da534SJohn Baldwin 		 * Binary block of data that might have printable characters.
11894e3da534SJohn Baldwin 		 * XXX If type|OUT, assume that the length is the syscall's
11904e3da534SJohn Baldwin 		 * return value.  Otherwise, assume that the length of the block
11914e3da534SJohn Baldwin 		 * is in the next syscall argument.
11924e3da534SJohn Baldwin 		 */
1193081e5c48SPav Lucistnik 		int max_string = trussinfo->strsize;
1194081e5c48SPav Lucistnik 		char tmp2[max_string + 1], *tmp3;
1195081e5c48SPav Lucistnik 		int len;
1196081e5c48SPav Lucistnik 		int truncated = 0;
1197081e5c48SPav Lucistnik 
1198081e5c48SPav Lucistnik 		if (sc->type & OUT)
11992b75c8adSJohn Baldwin 			len = retval[0];
1200081e5c48SPav Lucistnik 		else
1201081e5c48SPav Lucistnik 			len = args[sc->offset + 1];
1202081e5c48SPav Lucistnik 
12034e3da534SJohn Baldwin 		/*
12044e3da534SJohn Baldwin 		 * Don't print more than max_string characters, to avoid word
12054e3da534SJohn Baldwin 		 * wrap.  If we have to truncate put some ... after the string.
1206081e5c48SPav Lucistnik 		 */
1207081e5c48SPav Lucistnik 		if (len > max_string) {
1208081e5c48SPav Lucistnik 			len = max_string;
1209081e5c48SPav Lucistnik 			truncated = 1;
1210081e5c48SPav Lucistnik 		}
121194355cfdSAndrey Zonov 		if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len)
121294355cfdSAndrey Zonov 		    != -1) {
1213081e5c48SPav Lucistnik 			tmp3 = malloc(len * 4 + 1);
1214081e5c48SPav Lucistnik 			while (len) {
121594355cfdSAndrey Zonov 				if (strvisx(tmp3, tmp2, len,
121694355cfdSAndrey Zonov 				    VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
1217081e5c48SPav Lucistnik 					break;
1218081e5c48SPav Lucistnik 				len--;
1219081e5c48SPav Lucistnik 				truncated = 1;
122080c7cc1cSPedro F. Giffuni 			}
1221f083f689SJohn Baldwin 			fprintf(fp, "\"%s\"%s", tmp3, truncated ?
122294355cfdSAndrey Zonov 			    "..." : "");
1223081e5c48SPav Lucistnik 			free(tmp3);
1224d8984f48SDag-Erling Smørgrav 		} else {
1225f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1226081e5c48SPav Lucistnik 		}
1227081e5c48SPav Lucistnik 		break;
1228d8984f48SDag-Erling Smørgrav 	}
122968055893SJohn Baldwin 	case ExecArgs:
123068055893SJohn Baldwin 	case ExecEnv:
1231d8984f48SDag-Erling Smørgrav 	case StringArray: {
1232890843c1SJohn Baldwin 		uintptr_t addr;
1233890843c1SJohn Baldwin 		union {
1234890843c1SJohn Baldwin 			char *strarray[0];
1235890843c1SJohn Baldwin 			char buf[PAGE_SIZE];
1236890843c1SJohn Baldwin 		} u;
12379897b203SMatthew N. Dodd 		char *string;
1238890843c1SJohn Baldwin 		size_t len;
12392b75c8adSJohn Baldwin 		u_int first, i;
12409897b203SMatthew N. Dodd 
1241890843c1SJohn Baldwin 		/*
124268055893SJohn Baldwin 		 * Only parse argv[] and environment arrays from exec calls
124368055893SJohn Baldwin 		 * if requested.
124468055893SJohn Baldwin 		 */
124568055893SJohn Baldwin 		if (((sc->type & ARG_MASK) == ExecArgs &&
124668055893SJohn Baldwin 		    (trussinfo->flags & EXECVEARGS) == 0) ||
124768055893SJohn Baldwin 		    ((sc->type & ARG_MASK) == ExecEnv &&
124868055893SJohn Baldwin 		    (trussinfo->flags & EXECVEENVS) == 0)) {
124968055893SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
125068055893SJohn Baldwin 			break;
125168055893SJohn Baldwin 		}
125268055893SJohn Baldwin 
125368055893SJohn Baldwin 		/*
1254890843c1SJohn Baldwin 		 * Read a page of pointers at a time.  Punt if the top-level
1255890843c1SJohn Baldwin 		 * pointer is not aligned.  Note that the first read is of
1256890843c1SJohn Baldwin 		 * a partial page.
1257890843c1SJohn Baldwin 		 */
1258890843c1SJohn Baldwin 		addr = args[sc->offset];
1259890843c1SJohn Baldwin 		if (addr % sizeof(char *) != 0) {
1260890843c1SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1261890843c1SJohn Baldwin 			break;
12629897b203SMatthew N. Dodd 		}
12639897b203SMatthew N. Dodd 
1264890843c1SJohn Baldwin 		len = PAGE_SIZE - (addr & PAGE_MASK);
1265890843c1SJohn Baldwin 		if (get_struct(pid, (void *)addr, u.buf, len) == -1) {
1266890843c1SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1267890843c1SJohn Baldwin 			break;
12689897b203SMatthew N. Dodd 		}
1269890843c1SJohn Baldwin 
1270890843c1SJohn Baldwin 		fputc('[', fp);
1271890843c1SJohn Baldwin 		first = 1;
1272890843c1SJohn Baldwin 		i = 0;
1273890843c1SJohn Baldwin 		while (u.strarray[i] != NULL) {
1274890843c1SJohn Baldwin 			string = get_string(pid, u.strarray[i], 0);
1275890843c1SJohn Baldwin 			fprintf(fp, "%s \"%s\"", first ? "" : ",", string);
1276890843c1SJohn Baldwin 			free(string);
1277890843c1SJohn Baldwin 			first = 0;
1278890843c1SJohn Baldwin 
1279890843c1SJohn Baldwin 			i++;
1280890843c1SJohn Baldwin 			if (i == len / sizeof(char *)) {
1281890843c1SJohn Baldwin 				addr += len;
1282890843c1SJohn Baldwin 				len = PAGE_SIZE;
1283890843c1SJohn Baldwin 				if (get_struct(pid, (void *)addr, u.buf, len) ==
1284890843c1SJohn Baldwin 				    -1) {
1285890843c1SJohn Baldwin 					fprintf(fp, ", <inval>");
1286890843c1SJohn Baldwin 					break;
1287890843c1SJohn Baldwin 				}
1288890843c1SJohn Baldwin 				i = 0;
1289890843c1SJohn Baldwin 			}
1290890843c1SJohn Baldwin 		}
1291890843c1SJohn Baldwin 		fputs(" ]", fp);
12929897b203SMatthew N. Dodd 		break;
1293d8984f48SDag-Erling Smørgrav 	}
129410aeefc9SMarcel Moolenaar #ifdef __LP64__
129510aeefc9SMarcel Moolenaar 	case Quad:
129672df19e7SJohn Baldwin 		fprintf(fp, "%ld", args[sc->offset]);
129772df19e7SJohn Baldwin 		break;
129872df19e7SJohn Baldwin 	case QuadHex:
1299f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
130010aeefc9SMarcel Moolenaar 		break;
130110aeefc9SMarcel Moolenaar #else
130272df19e7SJohn Baldwin 	case Quad:
130372df19e7SJohn Baldwin 	case QuadHex: {
130410aeefc9SMarcel Moolenaar 		unsigned long long ll;
13054e3da534SJohn Baldwin 
13062b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
13072b75c8adSJohn Baldwin 		ll = (unsigned long long)args[sc->offset + 1] << 32 |
13082b75c8adSJohn Baldwin 		    args[sc->offset];
13092b75c8adSJohn Baldwin #else
13102b75c8adSJohn Baldwin 		ll = (unsigned long long)args[sc->offset] << 32 |
13112b75c8adSJohn Baldwin 		    args[sc->offset + 1];
13122b75c8adSJohn Baldwin #endif
131372df19e7SJohn Baldwin 		if ((sc->type & ARG_MASK) == Quad)
131472df19e7SJohn Baldwin 			fprintf(fp, "%lld", ll);
131572df19e7SJohn Baldwin 		else
1316f083f689SJohn Baldwin 			fprintf(fp, "0x%llx", ll);
1317bbeaf6c0SSean Eric Fagan 		break;
1318bbeaf6c0SSean Eric Fagan 	}
131910aeefc9SMarcel Moolenaar #endif
1320bbeaf6c0SSean Eric Fagan 	case Ptr:
1321f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
1322bbeaf6c0SSean Eric Fagan 		break;
1323d8984f48SDag-Erling Smørgrav 	case Readlinkres: {
13242bae4eb3SAlfred Perlstein 		char *tmp2;
13254e3da534SJohn Baldwin 
13262b75c8adSJohn Baldwin 		if (retval[0] == -1)
13272bae4eb3SAlfred Perlstein 			break;
13282b75c8adSJohn Baldwin 		tmp2 = get_string(pid, (void*)args[sc->offset], retval[0]);
1329f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
13302bae4eb3SAlfred Perlstein 		free(tmp2);
13312bae4eb3SAlfred Perlstein 		break;
1332d8984f48SDag-Erling Smørgrav 	}
1333d8984f48SDag-Erling Smørgrav 	case Ioctl: {
13344e3da534SJohn Baldwin 		const char *temp;
13354e3da534SJohn Baldwin 		unsigned long cmd;
13364e3da534SJohn Baldwin 
13374e3da534SJohn Baldwin 		cmd = args[sc->offset];
1338265e5898SJohn Baldwin 		temp = sysdecode_ioctlname(cmd);
133994355cfdSAndrey Zonov 		if (temp)
1340f083f689SJohn Baldwin 			fputs(temp, fp);
134194355cfdSAndrey Zonov 		else {
1342f083f689SJohn Baldwin 			fprintf(fp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
13434e3da534SJohn Baldwin 			    cmd, cmd & IOC_OUT ? "R" : "",
13444e3da534SJohn Baldwin 			    cmd & IOC_IN ? "W" : "", IOCGROUP(cmd),
13454e3da534SJohn Baldwin 			    isprint(IOCGROUP(cmd)) ? (char)IOCGROUP(cmd) : '?',
13464e3da534SJohn Baldwin 			    cmd & 0xFF, IOCPARM_LEN(cmd));
1347081e5c48SPav Lucistnik 		}
1348081e5c48SPav Lucistnik 		break;
1349d8984f48SDag-Erling Smørgrav 	}
1350d8984f48SDag-Erling Smørgrav 	case Timespec: {
1351e45a5a0dSDavid Malone 		struct timespec ts;
13524e3da534SJohn Baldwin 
135394355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &ts,
135494355cfdSAndrey Zonov 		    sizeof(ts)) != -1)
1355a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%09ld }", (intmax_t)ts.tv_sec,
135694355cfdSAndrey Zonov 			    ts.tv_nsec);
1357e45a5a0dSDavid Malone 		else
1358f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1359e45a5a0dSDavid Malone 		break;
1360d8984f48SDag-Erling Smørgrav 	}
13617d897327SJohn Baldwin 	case Timespec2: {
13627d897327SJohn Baldwin 		struct timespec ts[2];
13637d897327SJohn Baldwin 		const char *sep;
13647d897327SJohn Baldwin 		unsigned int i;
13657d897327SJohn Baldwin 
13667d897327SJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts))
13677d897327SJohn Baldwin 		    != -1) {
13681e2ec671SJohn Baldwin 			fputs("{ ", fp);
13697d897327SJohn Baldwin 			sep = "";
13707d897327SJohn Baldwin 			for (i = 0; i < nitems(ts); i++) {
13717d897327SJohn Baldwin 				fputs(sep, fp);
13727d897327SJohn Baldwin 				sep = ", ";
13737d897327SJohn Baldwin 				switch (ts[i].tv_nsec) {
13747d897327SJohn Baldwin 				case UTIME_NOW:
13757d897327SJohn Baldwin 					fprintf(fp, "UTIME_NOW");
13767d897327SJohn Baldwin 					break;
13777d897327SJohn Baldwin 				case UTIME_OMIT:
13787d897327SJohn Baldwin 					fprintf(fp, "UTIME_OMIT");
13797d897327SJohn Baldwin 					break;
13807d897327SJohn Baldwin 				default:
1381a1436773SJohn Baldwin 					fprintf(fp, "%jd.%09ld",
1382a1436773SJohn Baldwin 					    (intmax_t)ts[i].tv_sec,
1383a1436773SJohn Baldwin 					    ts[i].tv_nsec);
13847d897327SJohn Baldwin 					break;
13857d897327SJohn Baldwin 				}
13867d897327SJohn Baldwin 			}
13871e2ec671SJohn Baldwin 			fputs(" }", fp);
13887d897327SJohn Baldwin 		} else
1389f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
13907d897327SJohn Baldwin 		break;
13917d897327SJohn Baldwin 	}
1392d8984f48SDag-Erling Smørgrav 	case Timeval: {
1393e45a5a0dSDavid Malone 		struct timeval tv;
13944e3da534SJohn Baldwin 
139594355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
139694355cfdSAndrey Zonov 		    != -1)
1397a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld }", (intmax_t)tv.tv_sec,
139894355cfdSAndrey Zonov 			    tv.tv_usec);
1399081e5c48SPav Lucistnik 		else
1400f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1401081e5c48SPav Lucistnik 		break;
1402d8984f48SDag-Erling Smørgrav 	}
1403d8984f48SDag-Erling Smørgrav 	case Timeval2: {
1404081e5c48SPav Lucistnik 		struct timeval tv[2];
14054e3da534SJohn Baldwin 
140694355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
140794355cfdSAndrey Zonov 		    != -1)
1408a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1409a1436773SJohn Baldwin 			    (intmax_t)tv[0].tv_sec, tv[0].tv_usec,
1410a1436773SJohn Baldwin 			    (intmax_t)tv[1].tv_sec, tv[1].tv_usec);
1411e45a5a0dSDavid Malone 		else
1412f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1413e45a5a0dSDavid Malone 		break;
1414d8984f48SDag-Erling Smørgrav 	}
1415d8984f48SDag-Erling Smørgrav 	case Itimerval: {
1416e45a5a0dSDavid Malone 		struct itimerval itv;
14174e3da534SJohn Baldwin 
141894355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &itv,
141994355cfdSAndrey Zonov 		    sizeof(itv)) != -1)
1420a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1421a1436773SJohn Baldwin 			    (intmax_t)itv.it_interval.tv_sec,
1422081e5c48SPav Lucistnik 			    itv.it_interval.tv_usec,
1423a1436773SJohn Baldwin 			    (intmax_t)itv.it_value.tv_sec,
1424081e5c48SPav Lucistnik 			    itv.it_value.tv_usec);
1425e45a5a0dSDavid Malone 		else
1426f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1427e45a5a0dSDavid Malone 		break;
1428d8984f48SDag-Erling Smørgrav 	}
14291c99a22aSSteven Hartland 	case LinuxSockArgs:
14301c99a22aSSteven Hartland 	{
14311c99a22aSSteven Hartland 		struct linux_socketcall_args largs;
14324e3da534SJohn Baldwin 
14331c99a22aSSteven Hartland 		if (get_struct(pid, (void *)args[sc->offset], (void *)&largs,
1434fb7eabb0SJohn Baldwin 		    sizeof(largs)) != -1)
1435f083f689SJohn Baldwin 			fprintf(fp, "{ %s, 0x%lx }",
1436fb7eabb0SJohn Baldwin 			    lookup(linux_socketcall_ops, largs.what, 10),
14370a46af44SJohn Baldwin 			    (long unsigned int)largs.args);
1438fb7eabb0SJohn Baldwin 		else
1439f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
14401c99a22aSSteven Hartland 		break;
14411c99a22aSSteven Hartland 	}
1442d8984f48SDag-Erling Smørgrav 	case Pollfd: {
1443e45a5a0dSDavid Malone 		/*
144494355cfdSAndrey Zonov 		 * XXX: A Pollfd argument expects the /next/ syscall argument
144594355cfdSAndrey Zonov 		 * to be the number of fds in the array. This matches the poll
144694355cfdSAndrey Zonov 		 * syscall.
1447e45a5a0dSDavid Malone 		 */
1448e45a5a0dSDavid Malone 		struct pollfd *pfd;
1449e45a5a0dSDavid Malone 		int numfds = args[sc->offset + 1];
1450f083f689SJohn Baldwin 		size_t bytes = sizeof(struct pollfd) * numfds;
1451f083f689SJohn Baldwin 		int i;
1452e45a5a0dSDavid Malone 
1453e45a5a0dSDavid Malone 		if ((pfd = malloc(bytes)) == NULL)
1454f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for pollfd array",
145594355cfdSAndrey Zonov 			    bytes);
145694355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], pfd, bytes)
145794355cfdSAndrey Zonov 		    != -1) {
1458f083f689SJohn Baldwin 			fputs("{", fp);
1459e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1460f083f689SJohn Baldwin 				fprintf(fp, " %d/%s", pfd[i].fd,
1461081e5c48SPav Lucistnik 				    xlookup_bits(poll_flags, pfd[i].events));
1462e45a5a0dSDavid Malone 			}
1463f083f689SJohn Baldwin 			fputs(" }", fp);
1464d8984f48SDag-Erling Smørgrav 		} else {
1465f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1466e45a5a0dSDavid Malone 		}
1467d8984f48SDag-Erling Smørgrav 		free(pfd);
1468e45a5a0dSDavid Malone 		break;
1469d8984f48SDag-Erling Smørgrav 	}
1470d8984f48SDag-Erling Smørgrav 	case Fd_set: {
1471e45a5a0dSDavid Malone 		/*
147294355cfdSAndrey Zonov 		 * XXX: A Fd_set argument expects the /first/ syscall argument
147394355cfdSAndrey Zonov 		 * to be the number of fds in the array.  This matches the
147494355cfdSAndrey Zonov 		 * select syscall.
1475e45a5a0dSDavid Malone 		 */
1476e45a5a0dSDavid Malone 		fd_set *fds;
1477e45a5a0dSDavid Malone 		int numfds = args[0];
1478f083f689SJohn Baldwin 		size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
1479f083f689SJohn Baldwin 		int i;
1480e45a5a0dSDavid Malone 
1481e45a5a0dSDavid Malone 		if ((fds = malloc(bytes)) == NULL)
1482f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for fd_set array",
148394355cfdSAndrey Zonov 			    bytes);
148494355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], fds, bytes)
148594355cfdSAndrey Zonov 		    != -1) {
1486f083f689SJohn Baldwin 			fputs("{", fp);
1487e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1488f083f689SJohn Baldwin 				if (FD_ISSET(i, fds))
1489f083f689SJohn Baldwin 					fprintf(fp, " %d", i);
1490e45a5a0dSDavid Malone 			}
1491f083f689SJohn Baldwin 			fputs(" }", fp);
149294355cfdSAndrey Zonov 		} else
1493f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1494d8984f48SDag-Erling Smørgrav 		free(fds);
1495e45a5a0dSDavid Malone 		break;
1496d8984f48SDag-Erling Smørgrav 	}
149734763d1cSJohn Baldwin 	case Signal:
1498f083f689SJohn Baldwin 		fputs(strsig2(args[sc->offset]), fp);
1499f0ebbc29SDag-Erling Smørgrav 		break;
1500d8984f48SDag-Erling Smørgrav 	case Sigset: {
1501081e5c48SPav Lucistnik 		long sig;
1502081e5c48SPav Lucistnik 		sigset_t ss;
1503f083f689SJohn Baldwin 		int i, first;
1504081e5c48SPav Lucistnik 
1505081e5c48SPav Lucistnik 		sig = args[sc->offset];
150694355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
150794355cfdSAndrey Zonov 		    sizeof(ss)) == -1) {
1508f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1509081e5c48SPav Lucistnik 			break;
1510081e5c48SPav Lucistnik 		}
1511f083f689SJohn Baldwin 		fputs("{ ", fp);
1512f083f689SJohn Baldwin 		first = 1;
1513d8984f48SDag-Erling Smørgrav 		for (i = 1; i < sys_nsig; i++) {
151434763d1cSJohn Baldwin 			if (sigismember(&ss, i)) {
1515f083f689SJohn Baldwin 				fprintf(fp, "%s%s", !first ? "|" : "",
15169289f547SJohn Baldwin 				    strsig2(i));
1517f083f689SJohn Baldwin 				first = 0;
151834763d1cSJohn Baldwin 			}
1519081e5c48SPav Lucistnik 		}
1520f083f689SJohn Baldwin 		if (!first)
1521f083f689SJohn Baldwin 			fputc(' ', fp);
1522f083f689SJohn Baldwin 		fputc('}', fp);
1523081e5c48SPav Lucistnik 		break;
1524d8984f48SDag-Erling Smørgrav 	}
15259289f547SJohn Baldwin 	case Sigprocmask:
15269289f547SJohn Baldwin 		print_integer_arg(sysdecode_sigprocmask_how, fp,
15279289f547SJohn Baldwin 		    args[sc->offset]);
1528894b8f7aSAlfred Perlstein 		break;
15299289f547SJohn Baldwin 	case Fcntlflag:
15304e3da534SJohn Baldwin 		/* XXX: Output depends on the value of the previous argument. */
15319289f547SJohn Baldwin 		if (sysdecode_fcntl_arg_p(args[sc->offset - 1]))
15329289f547SJohn Baldwin 			sysdecode_fcntl_arg(fp, args[sc->offset - 1],
15339289f547SJohn Baldwin 			    args[sc->offset], 16);
1534081e5c48SPav Lucistnik 		break;
1535081e5c48SPav Lucistnik 	case Open:
15369289f547SJohn Baldwin 		print_mask_arg(sysdecode_open_flags, fp, args[sc->offset]);
1537081e5c48SPav Lucistnik 		break;
1538081e5c48SPav Lucistnik 	case Fcntl:
15399289f547SJohn Baldwin 		print_integer_arg(sysdecode_fcntl_cmd, fp, args[sc->offset]);
1540081e5c48SPav Lucistnik 		break;
1541894b8f7aSAlfred Perlstein 	case Mprot:
15429289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_prot, fp, args[sc->offset]);
1543894b8f7aSAlfred Perlstein 		break;
15449289f547SJohn Baldwin 	case Mmapflags:
15459289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_flags, fp, args[sc->offset]);
1546894b8f7aSAlfred Perlstein 		break;
1547fde3a7d1SAlfred Perlstein 	case Whence:
15489289f547SJohn Baldwin 		print_integer_arg(sysdecode_whence, fp, args[sc->offset]);
1549081e5c48SPav Lucistnik 		break;
1550081e5c48SPav Lucistnik 	case Sockdomain:
15519289f547SJohn Baldwin 		print_integer_arg(sysdecode_socketdomain, fp, args[sc->offset]);
1552081e5c48SPav Lucistnik 		break;
15539289f547SJohn Baldwin 	case Socktype:
15549289f547SJohn Baldwin 		print_mask_arg(sysdecode_socket_type, fp, args[sc->offset]);
1555081e5c48SPav Lucistnik 		break;
1556081e5c48SPav Lucistnik 	case Shutdown:
15579289f547SJohn Baldwin 		print_integer_arg(sysdecode_shutdown_how, fp, args[sc->offset]);
1558081e5c48SPav Lucistnik 		break;
1559081e5c48SPav Lucistnik 	case Resource:
15609289f547SJohn Baldwin 		print_integer_arg(sysdecode_rlimit, fp, args[sc->offset]);
1561081e5c48SPav Lucistnik 		break;
1562081e5c48SPav Lucistnik 	case Pathconf:
1563f083f689SJohn Baldwin 		fputs(xlookup(pathconf_arg, args[sc->offset]), fp);
1564fde3a7d1SAlfred Perlstein 		break;
15659e1db66eSMark Johnston 	case Rforkflags:
15669289f547SJohn Baldwin 		print_mask_arg(sysdecode_rfork_flags, fp, args[sc->offset]);
15679e1db66eSMark Johnston 		break;
1568d8984f48SDag-Erling Smørgrav 	case Sockaddr: {
15699ddd1412SDag-Erling Smørgrav 		char addr[64];
15701be5d704SMark Murray 		struct sockaddr_in *lsin;
15711be5d704SMark Murray 		struct sockaddr_in6 *lsin6;
1572dec17687SBrian Feldman 		struct sockaddr_un *sun;
1573dec17687SBrian Feldman 		struct sockaddr *sa;
157466917ca9SJohn Baldwin 		socklen_t len;
1575dec17687SBrian Feldman 		u_char *q;
15769ddd1412SDag-Erling Smørgrav 
1577a7a08c7eSMarcel Moolenaar 		if (args[sc->offset] == 0) {
1578f083f689SJohn Baldwin 			fputs("NULL", fp);
1579a7a08c7eSMarcel Moolenaar 			break;
1580a7a08c7eSMarcel Moolenaar 		}
1581a7a08c7eSMarcel Moolenaar 
15826a656761SAlfred Perlstein 		/*
158366917ca9SJohn Baldwin 		 * Extract the address length from the next argument.  If
158466917ca9SJohn Baldwin 		 * this is an output sockaddr (OUT is set), then the
158566917ca9SJohn Baldwin 		 * next argument is a pointer to a socklen_t.  Otherwise
158666917ca9SJohn Baldwin 		 * the next argument contains a socklen_t by value.
15876a656761SAlfred Perlstein 		 */
158866917ca9SJohn Baldwin 		if (sc->type & OUT) {
158966917ca9SJohn Baldwin 			if (get_struct(pid, (void *)args[sc->offset + 1],
159066917ca9SJohn Baldwin 			    &len, sizeof(len)) == -1) {
159166917ca9SJohn Baldwin 				fprintf(fp, "0x%lx", args[sc->offset]);
15926a656761SAlfred Perlstein 				break;
15936a656761SAlfred Perlstein 			}
159466917ca9SJohn Baldwin 		} else
159566917ca9SJohn Baldwin 			len = args[sc->offset + 1];
159666917ca9SJohn Baldwin 
159766917ca9SJohn Baldwin 		/* If the length is too small, just bail. */
159866917ca9SJohn Baldwin 		if (len < sizeof(*sa)) {
1599f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1600f083f689SJohn Baldwin 			break;
16019ddd1412SDag-Erling Smørgrav 		}
1602dec17687SBrian Feldman 
160366917ca9SJohn Baldwin 		sa = calloc(1, len);
160466917ca9SJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], sa, len) == -1) {
160566917ca9SJohn Baldwin 			free(sa);
160666917ca9SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
160766917ca9SJohn Baldwin 			break;
160866917ca9SJohn Baldwin 		}
160966917ca9SJohn Baldwin 
161066917ca9SJohn Baldwin 		switch (sa->sa_family) {
1611dec17687SBrian Feldman 		case AF_INET:
161266917ca9SJohn Baldwin 			if (len < sizeof(*lsin))
161366917ca9SJohn Baldwin 				goto sockaddr_short;
161466917ca9SJohn Baldwin 			lsin = (struct sockaddr_in *)(void *)sa;
16154e3da534SJohn Baldwin 			inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr));
1616f083f689SJohn Baldwin 			fprintf(fp, "{ AF_INET %s:%d }", addr,
161794355cfdSAndrey Zonov 			    htons(lsin->sin_port));
1618dec17687SBrian Feldman 			break;
1619dec17687SBrian Feldman 		case AF_INET6:
162066917ca9SJohn Baldwin 			if (len < sizeof(*lsin6))
162166917ca9SJohn Baldwin 				goto sockaddr_short;
162266917ca9SJohn Baldwin 			lsin6 = (struct sockaddr_in6 *)(void *)sa;
162394355cfdSAndrey Zonov 			inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
16244e3da534SJohn Baldwin 			    sizeof(addr));
1625f083f689SJohn Baldwin 			fprintf(fp, "{ AF_INET6 [%s]:%d }", addr,
162694355cfdSAndrey Zonov 			    htons(lsin6->sin6_port));
1627dec17687SBrian Feldman 			break;
1628dec17687SBrian Feldman 		case AF_UNIX:
162966917ca9SJohn Baldwin 			sun = (struct sockaddr_un *)sa;
163066917ca9SJohn Baldwin 			fprintf(fp, "{ AF_UNIX \"%.*s\" }",
163166917ca9SJohn Baldwin 			    (int)(len - offsetof(struct sockaddr_un, sun_path)),
163266917ca9SJohn Baldwin 			    sun->sun_path);
1633dec17687SBrian Feldman 			break;
1634dec17687SBrian Feldman 		default:
163566917ca9SJohn Baldwin 		sockaddr_short:
1636f083f689SJohn Baldwin 			fprintf(fp,
1637f083f689SJohn Baldwin 			    "{ sa_len = %d, sa_family = %d, sa_data = {",
1638f083f689SJohn Baldwin 			    (int)sa->sa_len, (int)sa->sa_family);
1639f083f689SJohn Baldwin 			for (q = (u_char *)sa->sa_data;
164066917ca9SJohn Baldwin 			     q < (u_char *)sa + len; q++)
1641f083f689SJohn Baldwin 				fprintf(fp, "%s 0x%02x",
1642f083f689SJohn Baldwin 				    q == (u_char *)sa->sa_data ? "" : ",",
1643f083f689SJohn Baldwin 				    *q);
1644f083f689SJohn Baldwin 			fputs(" } }", fp);
1645dec17687SBrian Feldman 		}
164666917ca9SJohn Baldwin 		free(sa);
16479ddd1412SDag-Erling Smørgrav 		break;
1648d8984f48SDag-Erling Smørgrav 	}
1649d8984f48SDag-Erling Smørgrav 	case Sigaction: {
1650e45a5a0dSDavid Malone 		struct sigaction sa;
1651e45a5a0dSDavid Malone 
165294355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa))
165394355cfdSAndrey Zonov 		    != -1) {
1654f083f689SJohn Baldwin 			fputs("{ ", fp);
1655e45a5a0dSDavid Malone 			if (sa.sa_handler == SIG_DFL)
1656f083f689SJohn Baldwin 				fputs("SIG_DFL", fp);
1657e45a5a0dSDavid Malone 			else if (sa.sa_handler == SIG_IGN)
1658f083f689SJohn Baldwin 				fputs("SIG_IGN", fp);
1659e45a5a0dSDavid Malone 			else
1660f083f689SJohn Baldwin 				fprintf(fp, "%p", sa.sa_handler);
1661f083f689SJohn Baldwin 			fprintf(fp, " %s ss_t }",
1662081e5c48SPav Lucistnik 			    xlookup_bits(sigaction_flags, sa.sa_flags));
166394355cfdSAndrey Zonov 		} else
1664f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1665e45a5a0dSDavid Malone 		break;
1666d8984f48SDag-Erling Smørgrav 	}
1667d8984f48SDag-Erling Smørgrav 	case Kevent: {
1668081e5c48SPav Lucistnik 		/*
16694e3da534SJohn Baldwin 		 * XXX XXX: The size of the array is determined by either the
1670081e5c48SPav Lucistnik 		 * next syscall argument, or by the syscall return value,
1671081e5c48SPav Lucistnik 		 * depending on which argument number we are.  This matches the
1672081e5c48SPav Lucistnik 		 * kevent syscall, but luckily that's the only syscall that uses
1673081e5c48SPav Lucistnik 		 * them.
1674081e5c48SPav Lucistnik 		 */
1675081e5c48SPav Lucistnik 		struct kevent *ke;
1676081e5c48SPav Lucistnik 		int numevents = -1;
1677f083f689SJohn Baldwin 		size_t bytes;
1678f083f689SJohn Baldwin 		int i;
1679081e5c48SPav Lucistnik 
1680081e5c48SPav Lucistnik 		if (sc->offset == 1)
1681081e5c48SPav Lucistnik 			numevents = args[sc->offset+1];
16822b75c8adSJohn Baldwin 		else if (sc->offset == 3 && retval[0] != -1)
16832b75c8adSJohn Baldwin 			numevents = retval[0];
1684081e5c48SPav Lucistnik 
1685f083f689SJohn Baldwin 		if (numevents >= 0) {
1686081e5c48SPav Lucistnik 			bytes = sizeof(struct kevent) * numevents;
1687081e5c48SPav Lucistnik 			if ((ke = malloc(bytes)) == NULL)
1688f083f689SJohn Baldwin 				err(1,
1689f083f689SJohn Baldwin 				    "Cannot malloc %zu bytes for kevent array",
169094355cfdSAndrey Zonov 				    bytes);
1691f083f689SJohn Baldwin 		} else
1692f083f689SJohn Baldwin 			ke = NULL;
169394355cfdSAndrey Zonov 		if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset],
169494355cfdSAndrey Zonov 		    ke, bytes) != -1) {
1695f083f689SJohn Baldwin 			fputc('{', fp);
1696c915ff03SJohn Baldwin 			for (i = 0; i < numevents; i++) {
1697c915ff03SJohn Baldwin 				fputc(' ', fp);
1698c915ff03SJohn Baldwin 				print_kevent(fp, &ke[i], sc->offset == 1);
1699c915ff03SJohn Baldwin 			}
1700f083f689SJohn Baldwin 			fputs(" }", fp);
1701d8984f48SDag-Erling Smørgrav 		} else {
1702f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1703081e5c48SPav Lucistnik 		}
1704d8984f48SDag-Erling Smørgrav 		free(ke);
1705081e5c48SPav Lucistnik 		break;
1706d8984f48SDag-Erling Smørgrav 	}
1707d8984f48SDag-Erling Smørgrav 	case Stat: {
1708081e5c48SPav Lucistnik 		struct stat st;
17094e3da534SJohn Baldwin 
171094355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st))
171194355cfdSAndrey Zonov 		    != -1) {
1712081e5c48SPav Lucistnik 			char mode[12];
17134e3da534SJohn Baldwin 
1714081e5c48SPav Lucistnik 			strmode(st.st_mode, mode);
1715f083f689SJohn Baldwin 			fprintf(fp,
1716b38fbc2eSJohn Baldwin 			    "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode,
1717b38fbc2eSJohn Baldwin 			    (uintmax_t)st.st_ino, (intmax_t)st.st_size,
171894355cfdSAndrey Zonov 			    (long)st.st_blksize);
1719d8984f48SDag-Erling Smørgrav 		} else {
1720f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1721081e5c48SPav Lucistnik 		}
1722081e5c48SPav Lucistnik 		break;
1723d8984f48SDag-Erling Smørgrav 	}
1724a776866bSBryan Drewery 	case StatFs: {
1725a776866bSBryan Drewery 		unsigned int i;
1726a776866bSBryan Drewery 		struct statfs buf;
17270a71c082SBryan Drewery 
1728a776866bSBryan Drewery 		if (get_struct(pid, (void *)args[sc->offset], &buf,
1729a776866bSBryan Drewery 		    sizeof(buf)) != -1) {
1730a776866bSBryan Drewery 			char fsid[17];
1731a776866bSBryan Drewery 
1732a776866bSBryan Drewery 			bzero(fsid, sizeof(fsid));
1733a776866bSBryan Drewery 			if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) {
1734a776866bSBryan Drewery 			        for (i = 0; i < sizeof(buf.f_fsid); i++)
1735a776866bSBryan Drewery 					snprintf(&fsid[i*2],
1736a776866bSBryan Drewery 					    sizeof(fsid) - (i*2), "%02x",
1737a776866bSBryan Drewery 					    ((u_char *)&buf.f_fsid)[i]);
1738a776866bSBryan Drewery 			}
1739a776866bSBryan Drewery 			fprintf(fp,
1740a776866bSBryan Drewery 			    "{ fstypename=%s,mntonname=%s,mntfromname=%s,"
1741a776866bSBryan Drewery 			    "fsid=%s }", buf.f_fstypename, buf.f_mntonname,
1742a776866bSBryan Drewery 			    buf.f_mntfromname, fsid);
1743a776866bSBryan Drewery 		} else
1744a776866bSBryan Drewery 			fprintf(fp, "0x%lx", args[sc->offset]);
1745a776866bSBryan Drewery 		break;
1746a776866bSBryan Drewery 	}
1747a776866bSBryan Drewery 
1748d8984f48SDag-Erling Smørgrav 	case Rusage: {
1749081e5c48SPav Lucistnik 		struct rusage ru;
17504e3da534SJohn Baldwin 
175194355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru))
175294355cfdSAndrey Zonov 		    != -1) {
1753f083f689SJohn Baldwin 			fprintf(fp,
1754a1436773SJohn Baldwin 			    "{ u=%jd.%06ld,s=%jd.%06ld,in=%ld,out=%ld }",
1755a1436773SJohn Baldwin 			    (intmax_t)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
1756a1436773SJohn Baldwin 			    (intmax_t)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
1757081e5c48SPav Lucistnik 			    ru.ru_inblock, ru.ru_oublock);
175894355cfdSAndrey Zonov 		} else
1759f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1760081e5c48SPav Lucistnik 		break;
1761d8984f48SDag-Erling Smørgrav 	}
1762d8984f48SDag-Erling Smørgrav 	case Rlimit: {
1763081e5c48SPav Lucistnik 		struct rlimit rl;
17644e3da534SJohn Baldwin 
176594355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl))
176694355cfdSAndrey Zonov 		    != -1) {
1767f083f689SJohn Baldwin 			fprintf(fp, "{ cur=%ju,max=%ju }",
1768081e5c48SPav Lucistnik 			    rl.rlim_cur, rl.rlim_max);
176994355cfdSAndrey Zonov 		} else
1770f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1771081e5c48SPav Lucistnik 		break;
1772d8984f48SDag-Erling Smørgrav 	}
177334763d1cSJohn Baldwin 	case ExitStatus: {
177434763d1cSJohn Baldwin 		int status;
1775f083f689SJohn Baldwin 
177634763d1cSJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], &status,
177734763d1cSJohn Baldwin 		    sizeof(status)) != -1) {
1778f083f689SJohn Baldwin 			fputs("{ ", fp);
177934763d1cSJohn Baldwin 			if (WIFCONTINUED(status))
1780f083f689SJohn Baldwin 				fputs("CONTINUED", fp);
178134763d1cSJohn Baldwin 			else if (WIFEXITED(status))
1782f083f689SJohn Baldwin 				fprintf(fp, "EXITED,val=%d",
178334763d1cSJohn Baldwin 				    WEXITSTATUS(status));
178434763d1cSJohn Baldwin 			else if (WIFSIGNALED(status))
1785f083f689SJohn Baldwin 				fprintf(fp, "SIGNALED,sig=%s%s",
1786f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)),
178734763d1cSJohn Baldwin 				    WCOREDUMP(status) ? ",cored" : "");
178834763d1cSJohn Baldwin 			else
1789f083f689SJohn Baldwin 				fprintf(fp, "STOPPED,sig=%s",
1790f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)));
1791f083f689SJohn Baldwin 			fputs(" }", fp);
179234763d1cSJohn Baldwin 		} else
1793f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
179434763d1cSJohn Baldwin 		break;
179534763d1cSJohn Baldwin 	}
179634763d1cSJohn Baldwin 	case Waitoptions:
17979289f547SJohn Baldwin 		print_mask_arg(sysdecode_wait6_options, fp, args[sc->offset]);
179834763d1cSJohn Baldwin 		break;
179934763d1cSJohn Baldwin 	case Idtype:
18009289f547SJohn Baldwin 		print_integer_arg(sysdecode_idtype, fp, args[sc->offset]);
180134763d1cSJohn Baldwin 		break;
180255648840SJohn Baldwin 	case Procctl:
18039289f547SJohn Baldwin 		print_integer_arg(sysdecode_procctl_cmd, fp, args[sc->offset]);
180455648840SJohn Baldwin 		break;
1805fdb5bf37SJohn Baldwin 	case Umtxop:
18069289f547SJohn Baldwin 		print_integer_arg(sysdecode_umtx_op, fp, args[sc->offset]);
1807fdb5bf37SJohn Baldwin 		break;
18087d897327SJohn Baldwin 	case Atfd:
18099289f547SJohn Baldwin 		print_integer_arg(sysdecode_atfd, fp, args[sc->offset]);
18107d897327SJohn Baldwin 		break;
18117d897327SJohn Baldwin 	case Atflags:
1812f083f689SJohn Baldwin 		fputs(xlookup_bits(at_flags, args[sc->offset]), fp);
18137d897327SJohn Baldwin 		break;
18147d897327SJohn Baldwin 	case Accessmode:
18159289f547SJohn Baldwin 		print_mask_arg(sysdecode_access_mode, fp, args[sc->offset]);
18167d897327SJohn Baldwin 		break;
1817b289a8d7SJohn Baldwin 	case Sysarch:
1818f083f689SJohn Baldwin 		fputs(xlookup(sysarch_ops, args[sc->offset]), fp);
1819b289a8d7SJohn Baldwin 		break;
18202b75c8adSJohn Baldwin 	case PipeFds:
18212b75c8adSJohn Baldwin 		/*
18222b75c8adSJohn Baldwin 		 * The pipe() system call in the kernel returns its
18232b75c8adSJohn Baldwin 		 * two file descriptors via return values.  However,
18242b75c8adSJohn Baldwin 		 * the interface exposed by libc is that pipe()
18252b75c8adSJohn Baldwin 		 * accepts a pointer to an array of descriptors.
18262b75c8adSJohn Baldwin 		 * Format the output to match the libc API by printing
18272b75c8adSJohn Baldwin 		 * the returned file descriptors as a fake argument.
18282b75c8adSJohn Baldwin 		 *
18292b75c8adSJohn Baldwin 		 * Overwrite the first retval to signal a successful
18302b75c8adSJohn Baldwin 		 * return as well.
18312b75c8adSJohn Baldwin 		 */
18322b75c8adSJohn Baldwin 		fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]);
18332b75c8adSJohn Baldwin 		retval[0] = 0;
18342b75c8adSJohn Baldwin 		break;
1835195aef99SBryan Drewery 	case Utrace: {
1836195aef99SBryan Drewery 		size_t len;
1837195aef99SBryan Drewery 		void *utrace_addr;
1838195aef99SBryan Drewery 
1839195aef99SBryan Drewery 		len = args[sc->offset + 1];
1840195aef99SBryan Drewery 		utrace_addr = calloc(1, len);
1841195aef99SBryan Drewery 		if (get_struct(pid, (void *)args[sc->offset],
1842195aef99SBryan Drewery 		    (void *)utrace_addr, len) != -1)
1843195aef99SBryan Drewery 			print_utrace(fp, utrace_addr, len);
1844195aef99SBryan Drewery 		else
1845195aef99SBryan Drewery 			fprintf(fp, "0x%lx", args[sc->offset]);
1846195aef99SBryan Drewery 		free(utrace_addr);
1847195aef99SBryan Drewery 		break;
1848195aef99SBryan Drewery 	}
1849808d9805SEd Schouten 	case IntArray: {
1850808d9805SEd Schouten 		int descriptors[16];
1851808d9805SEd Schouten 		unsigned long i, ndescriptors;
1852808d9805SEd Schouten 		bool truncated;
1853808d9805SEd Schouten 
1854808d9805SEd Schouten 		ndescriptors = args[sc->offset + 1];
1855808d9805SEd Schouten 		truncated = false;
1856808d9805SEd Schouten 		if (ndescriptors > nitems(descriptors)) {
1857808d9805SEd Schouten 			ndescriptors = nitems(descriptors);
1858808d9805SEd Schouten 			truncated = true;
1859808d9805SEd Schouten 		}
1860808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset],
1861808d9805SEd Schouten 		    descriptors, ndescriptors * sizeof(descriptors[0])) != -1) {
1862808d9805SEd Schouten 			fprintf(fp, "{");
1863808d9805SEd Schouten 			for (i = 0; i < ndescriptors; i++)
1864808d9805SEd Schouten 				fprintf(fp, i == 0 ? " %d" : ", %d",
1865808d9805SEd Schouten 				    descriptors[i]);
1866808d9805SEd Schouten 			fprintf(fp, truncated ? ", ... }" : " }");
1867808d9805SEd Schouten 		} else
1868808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1869808d9805SEd Schouten 		break;
1870808d9805SEd Schouten 	}
18719289f547SJohn Baldwin 	case Pipe2:
18729289f547SJohn Baldwin 		print_mask_arg(sysdecode_pipe2_flags, fp, args[sc->offset]);
18739289f547SJohn Baldwin 		break;
1874bed418c8SJohn Baldwin 	case CapFcntlRights: {
1875bed418c8SJohn Baldwin 		uint32_t rights;
1876bed418c8SJohn Baldwin 
1877bed418c8SJohn Baldwin 		if (sc->type & OUT) {
1878bed418c8SJohn Baldwin 			if (get_struct(pid, (void *)args[sc->offset], &rights,
1879bed418c8SJohn Baldwin 			    sizeof(rights)) == -1) {
1880bed418c8SJohn Baldwin 				fprintf(fp, "0x%lx", args[sc->offset]);
1881bed418c8SJohn Baldwin 				break;
1882bed418c8SJohn Baldwin 			}
1883bed418c8SJohn Baldwin 		} else
1884bed418c8SJohn Baldwin 			rights = args[sc->offset];
1885bed418c8SJohn Baldwin 		print_mask_arg32(sysdecode_cap_fcntlrights, fp, rights);
1886bed418c8SJohn Baldwin 		break;
1887bed418c8SJohn Baldwin 	}
1888d2a97485SJohn Baldwin 	case Fadvice:
1889d2a97485SJohn Baldwin 		print_integer_arg(sysdecode_fadvice, fp, args[sc->offset]);
1890d2a97485SJohn Baldwin 		break;
189127459358SJohn Baldwin 	case FileFlags: {
189227459358SJohn Baldwin 		fflags_t rem;
189327459358SJohn Baldwin 
189427459358SJohn Baldwin 		if (!sysdecode_fileflags(fp, args[sc->offset], &rem))
189527459358SJohn Baldwin 			fprintf(fp, "0x%x", rem);
189627459358SJohn Baldwin 		else if (rem != 0)
189727459358SJohn Baldwin 			fprintf(fp, "|0x%x", rem);
189827459358SJohn Baldwin 		break;
189927459358SJohn Baldwin 	}
1900dd92181fSJohn Baldwin 	case Flockop:
1901dd92181fSJohn Baldwin 		print_mask_arg(sysdecode_flock_operation, fp, args[sc->offset]);
1902dd92181fSJohn Baldwin 		break;
1903ab43bedcSJohn Baldwin 	case Getfsstatmode:
1904ab43bedcSJohn Baldwin 		print_integer_arg(sysdecode_getfsstat_mode, fp,
1905ab43bedcSJohn Baldwin 		    args[sc->offset]);
1906ab43bedcSJohn Baldwin 		break;
190794e854c5SJohn Baldwin 	case Kldsymcmd:
190894e854c5SJohn Baldwin 		print_integer_arg(sysdecode_kldsym_cmd, fp, args[sc->offset]);
190994e854c5SJohn Baldwin 		break;
191094e854c5SJohn Baldwin 	case Kldunloadflags:
191194e854c5SJohn Baldwin 		print_integer_arg(sysdecode_kldunload_flags, fp,
191294e854c5SJohn Baldwin 		    args[sc->offset]);
191394e854c5SJohn Baldwin 		break;
191498fdbeecSJohn Baldwin 	case Madvice:
191598fdbeecSJohn Baldwin 		print_integer_arg(sysdecode_madvice, fp, args[sc->offset]);
191698fdbeecSJohn Baldwin 		break;
191758227c60SMichael Tuexen 	case Socklent:
191858227c60SMichael Tuexen 		fprintf(fp, "%u", (socklen_t)args[sc->offset]);
191958227c60SMichael Tuexen 		break;
1920*ecac235bSMichael Tuexen 	case Sockprotocol: {
1921*ecac235bSMichael Tuexen 		int protocol;
1922*ecac235bSMichael Tuexen 
1923*ecac235bSMichael Tuexen 		protocol = args[sc->offset];
1924*ecac235bSMichael Tuexen 		if (protocol == 0) {
1925*ecac235bSMichael Tuexen 			fputs("0", fp);
1926*ecac235bSMichael Tuexen 		} else {
1927*ecac235bSMichael Tuexen 			print_integer_arg(sysdecode_ipproto, fp, protocol);
1928*ecac235bSMichael Tuexen 		}
1929*ecac235bSMichael Tuexen 		break;
1930*ecac235bSMichael Tuexen 	}
1931808d9805SEd Schouten 
1932808d9805SEd Schouten 	case CloudABIAdvice:
1933808d9805SEd Schouten 		fputs(xlookup(cloudabi_advice, args[sc->offset]), fp);
1934808d9805SEd Schouten 		break;
1935808d9805SEd Schouten 	case CloudABIClockID:
1936808d9805SEd Schouten 		fputs(xlookup(cloudabi_clockid, args[sc->offset]), fp);
1937808d9805SEd Schouten 		break;
1938808d9805SEd Schouten 	case ClouduABIFDSFlags:
1939808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_fdsflags, args[sc->offset]), fp);
1940808d9805SEd Schouten 		break;
1941808d9805SEd Schouten 	case CloudABIFDStat: {
1942808d9805SEd Schouten 		cloudabi_fdstat_t fds;
1943808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &fds, sizeof(fds))
1944808d9805SEd Schouten 		    != -1) {
1945808d9805SEd Schouten 			fprintf(fp, "{ %s, ",
1946808d9805SEd Schouten 			    xlookup(cloudabi_filetype, fds.fs_filetype));
1947808d9805SEd Schouten 			fprintf(fp, "%s, ... }",
1948808d9805SEd Schouten 			    xlookup_bits(cloudabi_fdflags, fds.fs_flags));
1949808d9805SEd Schouten 		} else
1950808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1951808d9805SEd Schouten 		break;
1952808d9805SEd Schouten 	}
1953808d9805SEd Schouten 	case CloudABIFileStat: {
1954808d9805SEd Schouten 		cloudabi_filestat_t fsb;
1955808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &fsb, sizeof(fsb))
1956808d9805SEd Schouten 		    != -1)
19579ba32307SJohn Baldwin 			fprintf(fp, "{ %s, %ju }",
1958808d9805SEd Schouten 			    xlookup(cloudabi_filetype, fsb.st_filetype),
19599ba32307SJohn Baldwin 			    (uintmax_t)fsb.st_size);
1960808d9805SEd Schouten 		else
1961808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1962808d9805SEd Schouten 		break;
1963808d9805SEd Schouten 	}
1964808d9805SEd Schouten 	case CloudABIFileType:
1965808d9805SEd Schouten 		fputs(xlookup(cloudabi_filetype, args[sc->offset]), fp);
1966808d9805SEd Schouten 		break;
1967808d9805SEd Schouten 	case CloudABIFSFlags:
1968808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_fsflags, args[sc->offset]), fp);
1969808d9805SEd Schouten 		break;
1970808d9805SEd Schouten 	case CloudABILookup:
1971808d9805SEd Schouten 		if ((args[sc->offset] & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) != 0)
1972808d9805SEd Schouten 			fprintf(fp, "%d|LOOKUP_SYMLINK_FOLLOW",
1973808d9805SEd Schouten 			    (int)args[sc->offset]);
1974808d9805SEd Schouten 		else
1975808d9805SEd Schouten 			fprintf(fp, "%d", (int)args[sc->offset]);
1976808d9805SEd Schouten 		break;
1977808d9805SEd Schouten 	case CloudABIMFlags:
1978808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_mflags, args[sc->offset]), fp);
1979808d9805SEd Schouten 		break;
1980808d9805SEd Schouten 	case CloudABIMProt:
1981808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_mprot, args[sc->offset]), fp);
1982808d9805SEd Schouten 		break;
1983808d9805SEd Schouten 	case CloudABIMSFlags:
1984808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_msflags, args[sc->offset]), fp);
1985808d9805SEd Schouten 		break;
1986808d9805SEd Schouten 	case CloudABIOFlags:
1987808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_oflags, args[sc->offset]), fp);
1988808d9805SEd Schouten 		break;
1989808d9805SEd Schouten 	case CloudABISDFlags:
1990808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_sdflags, args[sc->offset]), fp);
1991808d9805SEd Schouten 		break;
1992808d9805SEd Schouten 	case CloudABISignal:
1993808d9805SEd Schouten 		fputs(xlookup(cloudabi_signal, args[sc->offset]), fp);
1994808d9805SEd Schouten 		break;
1995808d9805SEd Schouten 	case CloudABISockStat: {
1996808d9805SEd Schouten 		cloudabi_sockstat_t ss;
1997808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &ss, sizeof(ss))
1998808d9805SEd Schouten 		    != -1) {
1999808d9805SEd Schouten 			fprintf(fp, "{ %s, ", xlookup(
2000808d9805SEd Schouten 			    cloudabi_sa_family, ss.ss_sockname.sa_family));
2001808d9805SEd Schouten 			fprintf(fp, "%s, ", xlookup(
2002808d9805SEd Schouten 			    cloudabi_sa_family, ss.ss_peername.sa_family));
2003808d9805SEd Schouten 			fprintf(fp, "%s, ", xlookup(
2004808d9805SEd Schouten 			    cloudabi_errno, ss.ss_error));
2005808d9805SEd Schouten 			fprintf(fp, "%s }", xlookup_bits(
2006808d9805SEd Schouten 			    cloudabi_ssstate, ss.ss_state));
2007808d9805SEd Schouten 		} else
2008808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
2009808d9805SEd Schouten 		break;
2010808d9805SEd Schouten 	}
2011808d9805SEd Schouten 	case CloudABISSFlags:
2012808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_ssflags, args[sc->offset]), fp);
2013808d9805SEd Schouten 		break;
2014808d9805SEd Schouten 	case CloudABITimestamp:
2015808d9805SEd Schouten 		fprintf(fp, "%lu.%09lus", args[sc->offset] / 1000000000,
2016808d9805SEd Schouten 		    args[sc->offset] % 1000000000);
2017808d9805SEd Schouten 		break;
2018808d9805SEd Schouten 	case CloudABIULFlags:
2019808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_ulflags, args[sc->offset]), fp);
2020808d9805SEd Schouten 		break;
2021808d9805SEd Schouten 	case CloudABIWhence:
2022808d9805SEd Schouten 		fputs(xlookup(cloudabi_whence, args[sc->offset]), fp);
2023808d9805SEd Schouten 		break;
2024808d9805SEd Schouten 
2025081e5c48SPav Lucistnik 	default:
2026081e5c48SPav Lucistnik 		errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
2027bbeaf6c0SSean Eric Fagan 	}
2028f083f689SJohn Baldwin 	fclose(fp);
2029d8984f48SDag-Erling Smørgrav 	return (tmp);
2030bbeaf6c0SSean Eric Fagan }
2031bbeaf6c0SSean Eric Fagan 
2032bbeaf6c0SSean Eric Fagan /*
203300ddbdf2SJohn Baldwin  * Print (to outfile) the system call and its arguments.
2034bbeaf6c0SSean Eric Fagan  */
2035bbeaf6c0SSean Eric Fagan void
203600ddbdf2SJohn Baldwin print_syscall(struct trussinfo *trussinfo)
2037d8984f48SDag-Erling Smørgrav {
203800ddbdf2SJohn Baldwin 	struct threadinfo *t;
203900ddbdf2SJohn Baldwin 	const char *name;
204000ddbdf2SJohn Baldwin 	char **s_args;
204100ddbdf2SJohn Baldwin 	int i, len, nargs;
20420d0bd00eSMatthew N. Dodd 
204300ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
2044c03bfcc8SMatthew N. Dodd 
20451175b23fSJohn Baldwin 	name = t->cs.sc->name;
204600ddbdf2SJohn Baldwin 	nargs = t->cs.nargs;
204700ddbdf2SJohn Baldwin 	s_args = t->cs.s_args;
20480d0bd00eSMatthew N. Dodd 
2049d70876fdSJohn Baldwin 	len = print_line_prefix(trussinfo);
2050ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, "%s(", name);
2051c03bfcc8SMatthew N. Dodd 
2052bbeaf6c0SSean Eric Fagan 	for (i = 0; i < nargs; i++) {
205300ddbdf2SJohn Baldwin 		if (s_args[i] != NULL)
2054ec0bed25SMatthew N. Dodd 			len += fprintf(trussinfo->outfile, "%s", s_args[i]);
2055bbeaf6c0SSean Eric Fagan 		else
205694355cfdSAndrey Zonov 			len += fprintf(trussinfo->outfile,
205794355cfdSAndrey Zonov 			    "<missing argument>");
205894355cfdSAndrey Zonov 		len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ?
205994355cfdSAndrey Zonov 		    "," : "");
2060bbeaf6c0SSean Eric Fagan 	}
2061ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, ")");
20626cb533feSSean Eric Fagan 	for (i = 0; i < 6 - (len / 8); i++)
2063ec0bed25SMatthew N. Dodd 		fprintf(trussinfo->outfile, "\t");
20646cb533feSSean Eric Fagan }
20656cb533feSSean Eric Fagan 
20666cb533feSSean Eric Fagan void
206700ddbdf2SJohn Baldwin print_syscall_ret(struct trussinfo *trussinfo, int errorp, long *retval)
20681bcb5f5aSMarcel Moolenaar {
2069ee3b0f6eSDiomidis Spinellis 	struct timespec timediff;
207000ddbdf2SJohn Baldwin 	struct threadinfo *t;
207100ddbdf2SJohn Baldwin 	struct syscall *sc;
2072287b96ddSJohn Baldwin 	int error;
2073ee3b0f6eSDiomidis Spinellis 
207400ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
207500ddbdf2SJohn Baldwin 	sc = t->cs.sc;
2076ee3b0f6eSDiomidis Spinellis 	if (trussinfo->flags & COUNTONLY) {
207700ddbdf2SJohn Baldwin 		timespecsubt(&t->after, &t->before, &timediff);
2078d9dcc463SXin LI 		timespecadd(&sc->time, &timediff, &sc->time);
2079ee3b0f6eSDiomidis Spinellis 		sc->ncalls++;
2080ee3b0f6eSDiomidis Spinellis 		if (errorp)
2081ee3b0f6eSDiomidis Spinellis 			sc->nerror++;
2082ee3b0f6eSDiomidis Spinellis 		return;
2083ee3b0f6eSDiomidis Spinellis 	}
2084d8984f48SDag-Erling Smørgrav 
208500ddbdf2SJohn Baldwin 	print_syscall(trussinfo);
20860cf21b4fSBrian Somers 	fflush(trussinfo->outfile);
2087b9befd33SJohn Baldwin 
2088b9befd33SJohn Baldwin 	if (retval == NULL) {
2089b9befd33SJohn Baldwin 		/*
2090b9befd33SJohn Baldwin 		 * This system call resulted in the current thread's exit,
2091b9befd33SJohn Baldwin 		 * so there is no return value or error to display.
2092b9befd33SJohn Baldwin 		 */
2093b9befd33SJohn Baldwin 		fprintf(trussinfo->outfile, "\n");
2094b9befd33SJohn Baldwin 		return;
2095b9befd33SJohn Baldwin 	}
2096b9befd33SJohn Baldwin 
2097287b96ddSJohn Baldwin 	if (errorp) {
2098287b96ddSJohn Baldwin 		error = sysdecode_abi_to_freebsd_errno(t->proc->abi->abi,
2099287b96ddSJohn Baldwin 		    retval[0]);
21002b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0],
2101287b96ddSJohn Baldwin 		    error == INT_MAX ? "Unknown error" : strerror(error));
2102287b96ddSJohn Baldwin 	}
21032b75c8adSJohn Baldwin #ifndef __LP64__
21046c61b0f3SBryan Drewery 	else if (sc->ret_type == 2) {
21052b75c8adSJohn Baldwin 		off_t off;
21062b75c8adSJohn Baldwin 
21072b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
21082b75c8adSJohn Baldwin 		off = (off_t)retval[1] << 32 | retval[0];
21092b75c8adSJohn Baldwin #else
21102b75c8adSJohn Baldwin 		off = (off_t)retval[0] << 32 | retval[1];
21112b75c8adSJohn Baldwin #endif
21122b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " = %jd (0x%jx)\n", (intmax_t)off,
21132b75c8adSJohn Baldwin 		    (intmax_t)off);
21146cb533feSSean Eric Fagan 	}
21152b75c8adSJohn Baldwin #endif
21162b75c8adSJohn Baldwin 	else
21172b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval[0],
21182b75c8adSJohn Baldwin 		    retval[0]);
2119bbeaf6c0SSean Eric Fagan }
2120ee3b0f6eSDiomidis Spinellis 
2121ee3b0f6eSDiomidis Spinellis void
2122ee3b0f6eSDiomidis Spinellis print_summary(struct trussinfo *trussinfo)
2123ee3b0f6eSDiomidis Spinellis {
2124ee3b0f6eSDiomidis Spinellis 	struct timespec total = {0, 0};
212594355cfdSAndrey Zonov 	struct syscall *sc;
2126ee3b0f6eSDiomidis Spinellis 	int ncall, nerror;
2127ee3b0f6eSDiomidis Spinellis 
2128ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
2129ee3b0f6eSDiomidis Spinellis 	    "syscall", "seconds", "calls", "errors");
2130ee3b0f6eSDiomidis Spinellis 	ncall = nerror = 0;
21316c61b0f3SBryan Drewery 	STAILQ_FOREACH(sc, &syscalls, entries)
2132ee3b0f6eSDiomidis Spinellis 		if (sc->ncalls) {
213355a8d2bbSJaakko Heinonen 			fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
213455a8d2bbSJaakko Heinonen 			    sc->name, (intmax_t)sc->time.tv_sec,
213555a8d2bbSJaakko Heinonen 			    sc->time.tv_nsec, sc->ncalls, sc->nerror);
2136d9dcc463SXin LI 			timespecadd(&total, &sc->time, &total);
2137ee3b0f6eSDiomidis Spinellis 			ncall += sc->ncalls;
2138ee3b0f6eSDiomidis Spinellis 			nerror += sc->nerror;
2139ee3b0f6eSDiomidis Spinellis 		}
2140ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n",
2141ee3b0f6eSDiomidis Spinellis 	    "", "-------------", "-------", "-------");
214255a8d2bbSJaakko Heinonen 	fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
214355a8d2bbSJaakko Heinonen 	    "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror);
2144ee3b0f6eSDiomidis Spinellis }
2145