xref: /freebsd/usr.bin/truss/syscalls.c (revision 832af457155320174f759c290d6784a10e7d4299)
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 } } },
177*832af457SMichael Tuexen 	{ .name = "getsockopt", .ret_type = 1, .nargs = 5,
178*832af457SMichael Tuexen 	  .args = { { Int, 0 }, { Sockoptlevel, 1 }, { Sockoptname, 2 },
179*832af457SMichael Tuexen 		    { Ptr | OUT, 3 }, { Ptr | OUT, 4 } } },
180f44fc79dSJohn Baldwin 	{ .name = "gettimeofday", .ret_type = 1, .nargs = 2,
181f44fc79dSJohn Baldwin 	  .args = { { Timeval | OUT, 0 }, { Ptr, 1 } } },
182f44fc79dSJohn Baldwin 	{ .name = "ioctl", .ret_type = 1, .nargs = 3,
183a776eeafSJohn Baldwin 	  .args = { { Int, 0 }, { Ioctl, 1 }, { Ptr, 2 } } },
184f44fc79dSJohn Baldwin 	{ .name = "kevent", .ret_type = 1, .nargs = 6,
185f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 },
186f44fc79dSJohn Baldwin 		    { Int, 4 }, { Timespec, 5 } } },
187f44fc79dSJohn Baldwin 	{ .name = "kill", .ret_type = 1, .nargs = 2,
188f44fc79dSJohn Baldwin 	  .args = { { Int | IN, 0 }, { Signal | IN, 1 } } },
189f44fc79dSJohn Baldwin 	{ .name = "kldfind", .ret_type = 1, .nargs = 1,
190f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
191f44fc79dSJohn Baldwin 	{ .name = "kldfirstmod", .ret_type = 1, .nargs = 1,
192f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
193f44fc79dSJohn Baldwin 	{ .name = "kldload", .ret_type = 1, .nargs = 1,
194f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
195f44fc79dSJohn Baldwin 	{ .name = "kldnext", .ret_type = 1, .nargs = 1,
196f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
197f44fc79dSJohn Baldwin 	{ .name = "kldstat", .ret_type = 1, .nargs = 2,
198f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr, 1 } } },
19994e854c5SJohn Baldwin 	{ .name = "kldsym", .ret_type = 1, .nargs = 3,
20094e854c5SJohn Baldwin 	  .args = { { Int, 0 }, { Kldsymcmd, 1 }, { Ptr, 2 } } },
201f44fc79dSJohn Baldwin 	{ .name = "kldunload", .ret_type = 1, .nargs = 1,
202f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
20394e854c5SJohn Baldwin 	{ .name = "kldunloadf", .ret_type = 1, .nargs = 2,
20494e854c5SJohn Baldwin 	  .args = { { Int, 0 }, { Kldunloadflags, 1 } } },
205f44fc79dSJohn Baldwin 	{ .name = "kse_release", .ret_type = 0, .nargs = 1,
206f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
207f44fc79dSJohn Baldwin 	{ .name = "lchflags", .ret_type = 1, .nargs = 2,
20827459358SJohn Baldwin 	  .args = { { Name | IN, 0 }, { FileFlags, 1 } } },
209f44fc79dSJohn Baldwin 	{ .name = "lchmod", .ret_type = 1, .nargs = 2,
210f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
211f44fc79dSJohn Baldwin 	{ .name = "lchown", .ret_type = 1, .nargs = 3,
212f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
2132b75c8adSJohn Baldwin 	{ .name = "link", .ret_type = 1, .nargs = 2,
214ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
2152b75c8adSJohn Baldwin 	{ .name = "linkat", .ret_type = 1, .nargs = 5,
2167d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 },
2177d897327SJohn Baldwin 		    { Atflags, 4 } } },
218e8d2c81dSMichael Tuexen 	{ .name = "listen", .ret_type = 1, .nargs = 2,
219e8d2c81dSMichael Tuexen 	  .args = { { Int, 0 }, { Int, 1 } } },
220f44fc79dSJohn Baldwin  	{ .name = "lseek", .ret_type = 2, .nargs = 3,
221c05cc0d6SJohn Baldwin 	  .args = { { Int, 0 }, { QuadHex, 1 }, { Whence, 2 } } },
222f44fc79dSJohn Baldwin 	{ .name = "lstat", .ret_type = 1, .nargs = 2,
223f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
224f44fc79dSJohn Baldwin 	{ .name = "lutimes", .ret_type = 1, .nargs = 2,
225f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
22698fdbeecSJohn Baldwin 	{ .name = "madvise", .ret_type = 1, .nargs = 3,
22798fdbeecSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Madvice, 2 } } },
228f44fc79dSJohn Baldwin 	{ .name = "mkdir", .ret_type = 1, .nargs = 2,
229f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
230f44fc79dSJohn Baldwin 	{ .name = "mkdirat", .ret_type = 1, .nargs = 3,
231f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
2322b75c8adSJohn Baldwin 	{ .name = "mkfifo", .ret_type = 1, .nargs = 2,
233e82ce59cSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
2342b75c8adSJohn Baldwin 	{ .name = "mkfifoat", .ret_type = 1, .nargs = 3,
2357d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
2362b75c8adSJohn Baldwin 	{ .name = "mknod", .ret_type = 1, .nargs = 3,
237e82ce59cSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } },
2382b75c8adSJohn Baldwin 	{ .name = "mknodat", .ret_type = 1, .nargs = 4,
2397d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } },
240f44fc79dSJohn Baldwin 	{ .name = "mmap", .ret_type = 1, .nargs = 6,
241e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Mprot, 2 }, { Mmapflags, 3 },
242c05cc0d6SJohn Baldwin 		    { Int, 4 }, { QuadHex, 5 } } },
243f44fc79dSJohn Baldwin 	{ .name = "modfind", .ret_type = 1, .nargs = 1,
244f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
2452b75c8adSJohn Baldwin 	{ .name = "mount", .ret_type = 1, .nargs = 4,
246ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } },
247f44fc79dSJohn Baldwin 	{ .name = "mprotect", .ret_type = 1, .nargs = 3,
248e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Mprot, 2 } } },
249f44fc79dSJohn Baldwin 	{ .name = "munmap", .ret_type = 1, .nargs = 2,
250e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 } } },
251f44fc79dSJohn Baldwin 	{ .name = "nanosleep", .ret_type = 1, .nargs = 1,
252f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
253f44fc79dSJohn Baldwin 	{ .name = "open", .ret_type = 1, .nargs = 3,
254f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } },
255f44fc79dSJohn Baldwin 	{ .name = "openat", .ret_type = 1, .nargs = 4,
256f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Open, 2 },
257f44fc79dSJohn Baldwin 		    { Octal, 3 } } },
258f44fc79dSJohn Baldwin 	{ .name = "pathconf", .ret_type = 1, .nargs = 2,
259f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Pathconf, 1 } } },
260f44fc79dSJohn Baldwin 	{ .name = "pipe", .ret_type = 1, .nargs = 1,
261f44fc79dSJohn Baldwin 	  .args = { { PipeFds | OUT, 0 } } },
262f44fc79dSJohn Baldwin 	{ .name = "pipe2", .ret_type = 1, .nargs = 2,
2639289f547SJohn Baldwin 	  .args = { { Ptr, 0 }, { Pipe2, 1 } } },
264f44fc79dSJohn Baldwin 	{ .name = "poll", .ret_type = 1, .nargs = 3,
265f44fc79dSJohn Baldwin 	  .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } },
266d2a97485SJohn Baldwin 	{ .name = "posix_fadvise", .ret_type = 1, .nargs = 4,
267d2a97485SJohn Baldwin 	  .args = { { Int, 0 }, { QuadHex, 1 }, { QuadHex, 2 },
268d2a97485SJohn Baldwin 		    { Fadvice, 3 } } },
269f44fc79dSJohn Baldwin 	{ .name = "posix_openpt", .ret_type = 1, .nargs = 1,
270f44fc79dSJohn Baldwin 	  .args = { { Open, 0 } } },
271f44fc79dSJohn Baldwin 	{ .name = "procctl", .ret_type = 1, .nargs = 4,
272c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { Procctl, 2 }, { Ptr, 3 } } },
273f44fc79dSJohn Baldwin 	{ .name = "read", .ret_type = 1, .nargs = 3,
274e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 } } },
275f44fc79dSJohn Baldwin 	{ .name = "readlink", .ret_type = 1, .nargs = 3,
276e261fb2aSJohn Baldwin 	  .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Sizet, 2 } } },
277f44fc79dSJohn Baldwin 	{ .name = "readlinkat", .ret_type = 1, .nargs = 4,
278f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 },
279e261fb2aSJohn Baldwin 		    { Sizet, 3 } } },
280ee3b0f6eSDiomidis Spinellis 	{ .name = "recvfrom", .ret_type = 1, .nargs = 6,
281e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 }, { Hex, 3 },
2820a46af44SJohn Baldwin 		    { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } },
283f44fc79dSJohn Baldwin 	{ .name = "rename", .ret_type = 1, .nargs = 2,
284f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Name, 1 } } },
285f44fc79dSJohn Baldwin 	{ .name = "renameat", .ret_type = 1, .nargs = 4,
286f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 } } },
287f44fc79dSJohn Baldwin 	{ .name = "rfork", .ret_type = 1, .nargs = 1,
288f44fc79dSJohn Baldwin 	  .args = { { Rforkflags, 0 } } },
289cca89ee3SBryan Drewery 	{ .name = "rmdir", .ret_type = 1, .nargs = 1,
290cca89ee3SBryan Drewery 	  .args = { { Name, 0 } } },
291ee3b0f6eSDiomidis Spinellis 	{ .name = "select", .ret_type = 1, .nargs = 5,
2920a46af44SJohn Baldwin 	  .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 },
2930a46af44SJohn Baldwin 		    { Timeval, 4 } } },
294f44fc79dSJohn Baldwin 	{ .name = "sendto", .ret_type = 1, .nargs = 6,
295e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 }, { Hex, 3 },
29658227c60SMichael Tuexen 		    { Sockaddr | IN, 4 }, { Socklent | IN, 5 } } },
297ee3b0f6eSDiomidis Spinellis 	{ .name = "setitimer", .ret_type = 1, .nargs = 3,
298ee3b0f6eSDiomidis Spinellis 	  .args = { { Int, 0 }, { Itimerval, 1 }, { Itimerval | OUT, 2 } } },
299f44fc79dSJohn Baldwin 	{ .name = "setrlimit", .ret_type = 1, .nargs = 2,
300f44fc79dSJohn Baldwin 	  .args = { { Resource, 0 }, { Rlimit | IN, 1 } } },
301*832af457SMichael Tuexen 	{ .name = "setsockopt", .ret_type = 1, .nargs = 5,
302*832af457SMichael Tuexen 	  .args = { { Int, 0 }, { Sockoptlevel, 1 }, { Sockoptname, 2 },
303*832af457SMichael Tuexen 		    { Ptr | IN, 3 }, { Socklent, 4 } } },
304f44fc79dSJohn Baldwin 	{ .name = "shutdown", .ret_type = 1, .nargs = 2,
305f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Shutdown, 1 } } },
306f44fc79dSJohn Baldwin 	{ .name = "sigaction", .ret_type = 1, .nargs = 3,
307f44fc79dSJohn Baldwin 	  .args = { { Signal, 0 }, { Sigaction | IN, 1 },
308f44fc79dSJohn Baldwin 		    { Sigaction | OUT, 2 } } },
3092b75c8adSJohn Baldwin 	{ .name = "sigpending", .ret_type = 1, .nargs = 1,
310b289a8d7SJohn Baldwin 	  .args = { { Sigset | OUT, 0 } } },
3112b75c8adSJohn Baldwin 	{ .name = "sigprocmask", .ret_type = 1, .nargs = 3,
312ee3b0f6eSDiomidis Spinellis 	  .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } },
3132b75c8adSJohn Baldwin 	{ .name = "sigqueue", .ret_type = 1, .nargs = 3,
314b289a8d7SJohn Baldwin 	  .args = { { Int, 0 }, { Signal, 1 }, { LongHex, 2 } } },
3152b75c8adSJohn Baldwin 	{ .name = "sigreturn", .ret_type = 1, .nargs = 1,
316b289a8d7SJohn Baldwin 	  .args = { { Ptr, 0 } } },
3172b75c8adSJohn Baldwin 	{ .name = "sigsuspend", .ret_type = 1, .nargs = 1,
318b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 } } },
319b289a8d7SJohn Baldwin 	{ .name = "sigtimedwait", .ret_type = 1, .nargs = 3,
320b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 }, { Timespec | IN, 2 } } },
321b289a8d7SJohn Baldwin 	{ .name = "sigwait", .ret_type = 1, .nargs = 2,
322b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 } } },
323b289a8d7SJohn Baldwin 	{ .name = "sigwaitinfo", .ret_type = 1, .nargs = 2,
324b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 } } },
325ee3b0f6eSDiomidis Spinellis 	{ .name = "socket", .ret_type = 1, .nargs = 3,
326ecac235bSMichael Tuexen 	  .args = { { Sockdomain, 0 }, { Socktype, 1 }, { Sockprotocol, 2 } } },
327f44fc79dSJohn Baldwin 	{ .name = "stat", .ret_type = 1, .nargs = 2,
328f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
329f44fc79dSJohn Baldwin 	{ .name = "statfs", .ret_type = 1, .nargs = 2,
330f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { StatFs | OUT, 1 } } },
331ee3b0f6eSDiomidis Spinellis 	{ .name = "symlink", .ret_type = 1, .nargs = 2,
332ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
3337d897327SJohn Baldwin 	{ .name = "symlinkat", .ret_type = 1, .nargs = 3,
3347d897327SJohn Baldwin 	  .args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } },
335f44fc79dSJohn Baldwin 	{ .name = "sysarch", .ret_type = 1, .nargs = 2,
336f44fc79dSJohn Baldwin 	  .args = { { Sysarch, 0 }, { Ptr, 1 } } },
337f44fc79dSJohn Baldwin 	{ .name = "thr_kill", .ret_type = 1, .nargs = 2,
338f44fc79dSJohn Baldwin 	  .args = { { Long, 0 }, { Signal, 1 } } },
339f44fc79dSJohn Baldwin 	{ .name = "thr_self", .ret_type = 1, .nargs = 1,
340f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 } } },
341f44fc79dSJohn Baldwin 	{ .name = "truncate", .ret_type = 1, .nargs = 2,
342c05cc0d6SJohn Baldwin 	  .args = { { Name | IN, 0 }, { QuadHex | IN, 1 } } },
343f44fc79dSJohn Baldwin #if 0
344f44fc79dSJohn Baldwin 	/* Does not exist */
345f44fc79dSJohn Baldwin 	{ .name = "umount", .ret_type = 1, .nargs = 2,
346f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 2 } } },
347f44fc79dSJohn Baldwin #endif
348f44fc79dSJohn Baldwin 	{ .name = "unlink", .ret_type = 1, .nargs = 1,
349f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
350f44fc79dSJohn Baldwin 	{ .name = "unlinkat", .ret_type = 1, .nargs = 3,
351f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } },
352f44fc79dSJohn Baldwin 	{ .name = "unmount", .ret_type = 1, .nargs = 2,
353f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 } } },
354f44fc79dSJohn Baldwin 	{ .name = "utimensat", .ret_type = 1, .nargs = 4,
355f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 },
356f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
357f44fc79dSJohn Baldwin 	{ .name = "utimes", .ret_type = 1, .nargs = 2,
358f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
359195aef99SBryan Drewery 	{ .name = "utrace", .ret_type = 1, .nargs = 1,
360195aef99SBryan Drewery 	  .args = { { Utrace, 0 } } },
36134763d1cSJohn Baldwin 	{ .name = "wait4", .ret_type = 1, .nargs = 4,
36234763d1cSJohn Baldwin 	  .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 },
36334763d1cSJohn Baldwin 		    { Rusage | OUT, 3 } } },
36434763d1cSJohn Baldwin 	{ .name = "wait6", .ret_type = 1, .nargs = 6,
365c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { ExitStatus | OUT, 2 },
366c05cc0d6SJohn Baldwin 		    { Waitoptions, 3 }, { Rusage | OUT, 4 }, { Ptr, 5 } } },
367f44fc79dSJohn Baldwin 	{ .name = "write", .ret_type = 1, .nargs = 3,
368e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 } } },
369f44fc79dSJohn Baldwin 
370f44fc79dSJohn Baldwin 	/* Linux ABI */
371f44fc79dSJohn Baldwin 	{ .name = "linux_access", .ret_type = 1, .nargs = 2,
372f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Accessmode, 1 } } },
373f44fc79dSJohn Baldwin 	{ .name = "linux_execve", .ret_type = 1, .nargs = 3,
374f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
375f44fc79dSJohn Baldwin 		    { ExecEnv | IN, 2 } } },
376f44fc79dSJohn Baldwin 	{ .name = "linux_lseek", .ret_type = 2, .nargs = 3,
377f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } },
378f44fc79dSJohn Baldwin 	{ .name = "linux_mkdir", .ret_type = 1, .nargs = 2,
379f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Int, 1 } } },
380f44fc79dSJohn Baldwin 	{ .name = "linux_newfstat", .ret_type = 1, .nargs = 2,
381f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr | OUT, 1 } } },
382f44fc79dSJohn Baldwin 	{ .name = "linux_newstat", .ret_type = 1, .nargs = 2,
383f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
384f44fc79dSJohn Baldwin 	{ .name = "linux_open", .ret_type = 1, .nargs = 3,
385f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } },
386f44fc79dSJohn Baldwin 	{ .name = "linux_readlink", .ret_type = 1, .nargs = 3,
387e261fb2aSJohn Baldwin 	  .args = { { Name, 0 }, { Name | OUT, 1 }, { Sizet, 2 } } },
388f44fc79dSJohn Baldwin 	{ .name = "linux_socketcall", .ret_type = 1, .nargs = 2,
389f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { LinuxSockArgs, 1 } } },
39064f4703bSJohn Baldwin 	{ .name = "linux_stat64", .ret_type = 1, .nargs = 2,
39164f4703bSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
392f44fc79dSJohn Baldwin 
393808d9805SEd Schouten 	/* CloudABI system calls. */
394808d9805SEd Schouten 	{ .name = "cloudabi_sys_clock_res_get", .ret_type = 1, .nargs = 1,
395808d9805SEd Schouten 	  .args = { { CloudABIClockID, 0 } } },
396808d9805SEd Schouten 	{ .name = "cloudabi_sys_clock_time_get", .ret_type = 1, .nargs = 2,
397808d9805SEd Schouten 	  .args = { { CloudABIClockID, 0 }, { CloudABITimestamp, 1 } } },
398808d9805SEd Schouten 	{ .name = "cloudabi_sys_condvar_signal", .ret_type = 1, .nargs = 3,
399808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 }, { UInt, 2 } } },
400808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_close", .ret_type = 1, .nargs = 1,
401808d9805SEd Schouten 	  .args = { { Int, 0 } } },
402808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_create1", .ret_type = 1, .nargs = 1,
403808d9805SEd Schouten 	  .args = { { CloudABIFileType, 0 } } },
404808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_create2", .ret_type = 1, .nargs = 2,
405808d9805SEd Schouten 	  .args = { { CloudABIFileType, 0 }, { PipeFds | OUT, 0 } } },
406808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_datasync", .ret_type = 1, .nargs = 1,
407808d9805SEd Schouten 	  .args = { { Int, 0 } } },
408808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_dup", .ret_type = 1, .nargs = 1,
409808d9805SEd Schouten 	  .args = { { Int, 0 } } },
410808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_replace", .ret_type = 1, .nargs = 2,
411808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 } } },
412808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_seek", .ret_type = 1, .nargs = 3,
413808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { CloudABIWhence, 2 } } },
414808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_stat_get", .ret_type = 1, .nargs = 2,
415808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFDStat | OUT, 1 } } },
416808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_stat_put", .ret_type = 1, .nargs = 3,
417808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFDStat | IN, 1 },
418808d9805SEd Schouten 	            { ClouduABIFDSFlags, 2 } } },
419808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_sync", .ret_type = 1, .nargs = 1,
420808d9805SEd Schouten 	  .args = { { Int, 0 } } },
421808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_advise", .ret_type = 1, .nargs = 4,
422808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 },
423808d9805SEd Schouten 	            { CloudABIAdvice, 3 } } },
424808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_allocate", .ret_type = 1, .nargs = 3,
425808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } },
426808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_create", .ret_type = 1, .nargs = 3,
427808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
428808d9805SEd Schouten 	            { CloudABIFileType, 3 } } },
429808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_link", .ret_type = 1, .nargs = 4,
430808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
431808d9805SEd Schouten 	            { Int, 3 }, { BinString | IN, 4 } } },
432808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_open", .ret_type = 1, .nargs = 4,
433808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
434808d9805SEd Schouten 	            { CloudABIOFlags, 3 }, { CloudABIFDStat | IN, 4 } } },
435808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_readdir", .ret_type = 1, .nargs = 4,
436808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 },
437808d9805SEd Schouten 	            { Int, 3 } } },
438808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_readlink", .ret_type = 1, .nargs = 4,
439808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
440808d9805SEd Schouten 	            { BinString | OUT, 3 }, { Int, 4 } } },
441808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_rename", .ret_type = 1, .nargs = 4,
442808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
443808d9805SEd Schouten 	            { Int, 3 }, { BinString | IN, 4 } } },
444808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_fget", .ret_type = 1, .nargs = 2,
445808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFileStat | OUT, 1 } } },
446808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_fput", .ret_type = 1, .nargs = 3,
447808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFileStat | IN, 1 },
448808d9805SEd Schouten 	            { CloudABIFSFlags, 2 } } },
449808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_get", .ret_type = 1, .nargs = 3,
450808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
451808d9805SEd Schouten 	            { CloudABIFileStat | OUT, 3 } } },
452808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_put", .ret_type = 1, .nargs = 4,
453808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
454808d9805SEd Schouten 	            { CloudABIFileStat | IN, 3 }, { CloudABIFSFlags, 4 } } },
455808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_symlink", .ret_type = 1, .nargs = 3,
456808d9805SEd Schouten 	  .args = { { BinString | IN, 0 },
457808d9805SEd Schouten 	            { Int, 2 }, { BinString | IN, 3 } } },
458808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_unlink", .ret_type = 1, .nargs = 3,
459808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
460808d9805SEd Schouten 	            { CloudABIULFlags, 3 } } },
461808d9805SEd Schouten 	{ .name = "cloudabi_sys_lock_unlock", .ret_type = 1, .nargs = 2,
462808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } },
463808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_advise", .ret_type = 1, .nargs = 3,
464808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIAdvice, 2 } } },
465808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_lock", .ret_type = 1, .nargs = 2,
466808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
467808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_map", .ret_type = 1, .nargs = 6,
468808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 },
469808d9805SEd Schouten 	            { CloudABIMFlags, 3 }, { Int, 4 }, { Int, 5 } } },
470808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_protect", .ret_type = 1, .nargs = 3,
471808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 } } },
472808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_sync", .ret_type = 1, .nargs = 3,
473808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMSFlags, 2 } } },
474808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_unlock", .ret_type = 1, .nargs = 2,
475808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
476808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_unmap", .ret_type = 1, .nargs = 2,
477808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
478808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_exec", .ret_type = 1, .nargs = 5,
479808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 },
480808d9805SEd Schouten 	            { IntArray, 3 }, { Int, 4 } } },
481808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_exit", .ret_type = 1, .nargs = 1,
482808d9805SEd Schouten 	  .args = { { Int, 0 } } },
483808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_fork", .ret_type = 1, .nargs = 0 },
484808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_raise", .ret_type = 1, .nargs = 1,
485808d9805SEd Schouten 	  .args = { { CloudABISignal, 0 } } },
486808d9805SEd Schouten 	{ .name = "cloudabi_sys_random_get", .ret_type = 1, .nargs = 2,
487808d9805SEd Schouten 	  .args = { { BinString | OUT, 0 }, { Int, 1 } } },
488808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_accept", .ret_type = 1, .nargs = 2,
489808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 } } },
490808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_bind", .ret_type = 1, .nargs = 3,
491808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } },
492808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_connect", .ret_type = 1, .nargs = 3,
493808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } },
494808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_listen", .ret_type = 1, .nargs = 2,
495808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 } } },
496808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_shutdown", .ret_type = 1, .nargs = 2,
497808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISDFlags, 1 } } },
498808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_stat_get", .ret_type = 1, .nargs = 3,
499808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 },
500808d9805SEd Schouten 	            { CloudABISSFlags, 2 } } },
501808d9805SEd Schouten 	{ .name = "cloudabi_sys_thread_exit", .ret_type = 1, .nargs = 2,
502808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } },
503808d9805SEd Schouten 	{ .name = "cloudabi_sys_thread_yield", .ret_type = 1, .nargs = 0 },
504808d9805SEd Schouten 
505ee3b0f6eSDiomidis Spinellis 	{ .name = 0 },
506bbeaf6c0SSean Eric Fagan };
5076c61b0f3SBryan Drewery static STAILQ_HEAD(, syscall) syscalls;
508bbeaf6c0SSean Eric Fagan 
509081e5c48SPav Lucistnik /* Xlat idea taken from strace */
510081e5c48SPav Lucistnik struct xlat {
511081e5c48SPav Lucistnik 	int val;
5125d2d083cSXin LI 	const char *str;
513081e5c48SPav Lucistnik };
514081e5c48SPav Lucistnik 
515081e5c48SPav Lucistnik #define	X(a)	{ a, #a },
516081e5c48SPav Lucistnik #define	XEND	{ 0, NULL }
517081e5c48SPav Lucistnik 
518081e5c48SPav Lucistnik static struct xlat kevent_filters[] = {
519081e5c48SPav Lucistnik 	X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE)
520081e5c48SPav Lucistnik 	X(EVFILT_PROC) X(EVFILT_SIGNAL) X(EVFILT_TIMER)
521d98d7ba0SJohn Baldwin 	X(EVFILT_PROCDESC) X(EVFILT_FS) X(EVFILT_LIO) X(EVFILT_USER)
522d98d7ba0SJohn Baldwin 	X(EVFILT_SENDFILE) XEND
523081e5c48SPav Lucistnik };
524081e5c48SPav Lucistnik 
525081e5c48SPav Lucistnik static struct xlat kevent_flags[] = {
526081e5c48SPav Lucistnik 	X(EV_ADD) X(EV_DELETE) X(EV_ENABLE) X(EV_DISABLE) X(EV_ONESHOT)
527d98d7ba0SJohn Baldwin 	X(EV_CLEAR) X(EV_RECEIPT) X(EV_DISPATCH) X(EV_FORCEONESHOT)
528d98d7ba0SJohn Baldwin 	X(EV_DROP) X(EV_FLAG1) X(EV_ERROR) X(EV_EOF) XEND
529081e5c48SPav Lucistnik };
530081e5c48SPav Lucistnik 
531c915ff03SJohn Baldwin static struct xlat kevent_user_ffctrl[] = {
532c915ff03SJohn Baldwin 	X(NOTE_FFNOP) X(NOTE_FFAND) X(NOTE_FFOR) X(NOTE_FFCOPY)
533c915ff03SJohn Baldwin 	XEND
534c915ff03SJohn Baldwin };
535c915ff03SJohn Baldwin 
536c915ff03SJohn Baldwin static struct xlat kevent_rdwr_fflags[] = {
537c915ff03SJohn Baldwin 	X(NOTE_LOWAT) X(NOTE_FILE_POLL) XEND
538c915ff03SJohn Baldwin };
539c915ff03SJohn Baldwin 
540c915ff03SJohn Baldwin static struct xlat kevent_vnode_fflags[] = {
541c915ff03SJohn Baldwin 	X(NOTE_DELETE) X(NOTE_WRITE) X(NOTE_EXTEND) X(NOTE_ATTRIB)
542c915ff03SJohn Baldwin 	X(NOTE_LINK) X(NOTE_RENAME) X(NOTE_REVOKE) XEND
543c915ff03SJohn Baldwin };
544c915ff03SJohn Baldwin 
545c915ff03SJohn Baldwin static struct xlat kevent_proc_fflags[] = {
546c915ff03SJohn Baldwin 	X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_TRACK) X(NOTE_TRACKERR)
547c915ff03SJohn Baldwin 	X(NOTE_CHILD) XEND
548c915ff03SJohn Baldwin };
549c915ff03SJohn Baldwin 
550c915ff03SJohn Baldwin static struct xlat kevent_timer_fflags[] = {
551c915ff03SJohn Baldwin 	X(NOTE_SECONDS) X(NOTE_MSECONDS) X(NOTE_USECONDS) X(NOTE_NSECONDS)
552c915ff03SJohn Baldwin 	XEND
553c915ff03SJohn Baldwin };
554c915ff03SJohn Baldwin 
555a02c83afSEd Schouten static struct xlat poll_flags[] = {
556081e5c48SPav Lucistnik 	X(POLLSTANDARD) X(POLLIN) X(POLLPRI) X(POLLOUT) X(POLLERR)
557081e5c48SPav Lucistnik 	X(POLLHUP) X(POLLNVAL) X(POLLRDNORM) X(POLLRDBAND)
558081e5c48SPav Lucistnik 	X(POLLWRBAND) X(POLLINIGNEOF) XEND
559081e5c48SPav Lucistnik };
560081e5c48SPav Lucistnik 
561081e5c48SPav Lucistnik static struct xlat sigaction_flags[] = {
562081e5c48SPav Lucistnik 	X(SA_ONSTACK) X(SA_RESTART) X(SA_RESETHAND) X(SA_NOCLDSTOP)
563081e5c48SPav Lucistnik 	X(SA_NODEFER) X(SA_NOCLDWAIT) X(SA_SIGINFO) XEND
564081e5c48SPav Lucistnik };
565081e5c48SPav Lucistnik 
566081e5c48SPav Lucistnik static struct xlat pathconf_arg[] = {
567081e5c48SPav Lucistnik 	X(_PC_LINK_MAX)  X(_PC_MAX_CANON)  X(_PC_MAX_INPUT)
568081e5c48SPav Lucistnik 	X(_PC_NAME_MAX) X(_PC_PATH_MAX) X(_PC_PIPE_BUF)
569081e5c48SPav Lucistnik 	X(_PC_CHOWN_RESTRICTED) X(_PC_NO_TRUNC) X(_PC_VDISABLE)
570081e5c48SPav Lucistnik 	X(_PC_ASYNC_IO) X(_PC_PRIO_IO) X(_PC_SYNC_IO)
571081e5c48SPav Lucistnik 	X(_PC_ALLOC_SIZE_MIN) X(_PC_FILESIZEBITS)
572081e5c48SPav Lucistnik 	X(_PC_REC_INCR_XFER_SIZE) X(_PC_REC_MAX_XFER_SIZE)
573081e5c48SPav Lucistnik 	X(_PC_REC_MIN_XFER_SIZE) X(_PC_REC_XFER_ALIGN)
574081e5c48SPav Lucistnik 	X(_PC_SYMLINK_MAX) X(_PC_ACL_EXTENDED) X(_PC_ACL_PATH_MAX)
575081e5c48SPav Lucistnik 	X(_PC_CAP_PRESENT) X(_PC_INF_PRESENT) X(_PC_MAC_PRESENT)
576d98d7ba0SJohn Baldwin 	X(_PC_ACL_NFS4) X(_PC_MIN_HOLE_SIZE) XEND
577081e5c48SPav Lucistnik };
578081e5c48SPav Lucistnik 
5797d897327SJohn Baldwin static struct xlat at_flags[] = {
5807d897327SJohn Baldwin 	X(AT_EACCESS) X(AT_SYMLINK_NOFOLLOW) X(AT_SYMLINK_FOLLOW)
5817d897327SJohn Baldwin 	X(AT_REMOVEDIR) XEND
5827d897327SJohn Baldwin };
5837d897327SJohn Baldwin 
584b289a8d7SJohn Baldwin static struct xlat sysarch_ops[] = {
585b289a8d7SJohn Baldwin #if defined(__i386__) || defined(__amd64__)
586b289a8d7SJohn Baldwin 	X(I386_GET_LDT) X(I386_SET_LDT) X(I386_GET_IOPERM) X(I386_SET_IOPERM)
587b289a8d7SJohn Baldwin 	X(I386_VM86) X(I386_GET_FSBASE) X(I386_SET_FSBASE) X(I386_GET_GSBASE)
588b289a8d7SJohn Baldwin 	X(I386_SET_GSBASE) X(I386_GET_XFPUSTATE) X(AMD64_GET_FSBASE)
589b289a8d7SJohn Baldwin 	X(AMD64_SET_FSBASE) X(AMD64_GET_GSBASE) X(AMD64_SET_GSBASE)
590b289a8d7SJohn Baldwin 	X(AMD64_GET_XFPUSTATE)
591b289a8d7SJohn Baldwin #endif
592b289a8d7SJohn Baldwin 	XEND
593b289a8d7SJohn Baldwin };
594fb7eabb0SJohn Baldwin 
595fb7eabb0SJohn Baldwin static struct xlat linux_socketcall_ops[] = {
596fb7eabb0SJohn Baldwin 	X(LINUX_SOCKET) X(LINUX_BIND) X(LINUX_CONNECT) X(LINUX_LISTEN)
597fb7eabb0SJohn Baldwin 	X(LINUX_ACCEPT) X(LINUX_GETSOCKNAME) X(LINUX_GETPEERNAME)
598fb7eabb0SJohn Baldwin 	X(LINUX_SOCKETPAIR) X(LINUX_SEND) X(LINUX_RECV) X(LINUX_SENDTO)
599fb7eabb0SJohn Baldwin 	X(LINUX_RECVFROM) X(LINUX_SHUTDOWN) X(LINUX_SETSOCKOPT)
600fb7eabb0SJohn Baldwin 	X(LINUX_GETSOCKOPT) X(LINUX_SENDMSG) X(LINUX_RECVMSG)
601fb7eabb0SJohn Baldwin 	XEND
602fb7eabb0SJohn Baldwin };
603fb7eabb0SJohn Baldwin 
604081e5c48SPav Lucistnik #undef X
605808d9805SEd Schouten #define	X(a)	{ CLOUDABI_##a, #a },
606808d9805SEd Schouten 
607808d9805SEd Schouten static struct xlat cloudabi_advice[] = {
608808d9805SEd Schouten 	X(ADVICE_DONTNEED) X(ADVICE_NOREUSE) X(ADVICE_NORMAL)
609808d9805SEd Schouten 	X(ADVICE_RANDOM) X(ADVICE_SEQUENTIAL) X(ADVICE_WILLNEED)
610808d9805SEd Schouten 	XEND
611808d9805SEd Schouten };
612808d9805SEd Schouten 
613808d9805SEd Schouten static struct xlat cloudabi_clockid[] = {
614808d9805SEd Schouten 	X(CLOCK_MONOTONIC) X(CLOCK_PROCESS_CPUTIME_ID)
615808d9805SEd Schouten 	X(CLOCK_REALTIME) X(CLOCK_THREAD_CPUTIME_ID)
616808d9805SEd Schouten 	XEND
617808d9805SEd Schouten };
618808d9805SEd Schouten 
619808d9805SEd Schouten static struct xlat cloudabi_errno[] = {
620808d9805SEd Schouten 	X(E2BIG) X(EACCES) X(EADDRINUSE) X(EADDRNOTAVAIL)
621808d9805SEd Schouten 	X(EAFNOSUPPORT) X(EAGAIN) X(EALREADY) X(EBADF) X(EBADMSG)
622808d9805SEd Schouten 	X(EBUSY) X(ECANCELED) X(ECHILD) X(ECONNABORTED) X(ECONNREFUSED)
623808d9805SEd Schouten 	X(ECONNRESET) X(EDEADLK) X(EDESTADDRREQ) X(EDOM) X(EDQUOT)
624808d9805SEd Schouten 	X(EEXIST) X(EFAULT) X(EFBIG) X(EHOSTUNREACH) X(EIDRM) X(EILSEQ)
625808d9805SEd Schouten 	X(EINPROGRESS) X(EINTR) X(EINVAL) X(EIO) X(EISCONN) X(EISDIR)
626808d9805SEd Schouten 	X(ELOOP) X(EMFILE) X(EMLINK) X(EMSGSIZE) X(EMULTIHOP)
627808d9805SEd Schouten 	X(ENAMETOOLONG) X(ENETDOWN) X(ENETRESET) X(ENETUNREACH)
628808d9805SEd Schouten 	X(ENFILE) X(ENOBUFS) X(ENODEV) X(ENOENT) X(ENOEXEC) X(ENOLCK)
629808d9805SEd Schouten 	X(ENOLINK) X(ENOMEM) X(ENOMSG) X(ENOPROTOOPT) X(ENOSPC)
630808d9805SEd Schouten 	X(ENOSYS) X(ENOTCONN) X(ENOTDIR) X(ENOTEMPTY) X(ENOTRECOVERABLE)
631808d9805SEd Schouten 	X(ENOTSOCK) X(ENOTSUP) X(ENOTTY) X(ENXIO) X(EOVERFLOW)
632808d9805SEd Schouten 	X(EOWNERDEAD) X(EPERM) X(EPIPE) X(EPROTO) X(EPROTONOSUPPORT)
633808d9805SEd Schouten 	X(EPROTOTYPE) X(ERANGE) X(EROFS) X(ESPIPE) X(ESRCH) X(ESTALE)
634808d9805SEd Schouten 	X(ETIMEDOUT) X(ETXTBSY) X(EXDEV) X(ENOTCAPABLE)
635808d9805SEd Schouten 	XEND
636808d9805SEd Schouten };
637808d9805SEd Schouten 
638808d9805SEd Schouten static struct xlat cloudabi_fdflags[] = {
639808d9805SEd Schouten 	X(FDFLAG_APPEND) X(FDFLAG_DSYNC) X(FDFLAG_NONBLOCK)
640808d9805SEd Schouten 	X(FDFLAG_RSYNC) X(FDFLAG_SYNC)
641808d9805SEd Schouten 	XEND
642808d9805SEd Schouten };
643808d9805SEd Schouten 
644808d9805SEd Schouten static struct xlat cloudabi_fdsflags[] = {
645808d9805SEd Schouten 	X(FDSTAT_FLAGS) X(FDSTAT_RIGHTS)
646808d9805SEd Schouten 	XEND
647808d9805SEd Schouten };
648808d9805SEd Schouten 
649808d9805SEd Schouten static struct xlat cloudabi_filetype[] = {
650808d9805SEd Schouten 	X(FILETYPE_UNKNOWN) X(FILETYPE_BLOCK_DEVICE)
651808d9805SEd Schouten 	X(FILETYPE_CHARACTER_DEVICE) X(FILETYPE_DIRECTORY)
652808d9805SEd Schouten 	X(FILETYPE_FIFO) X(FILETYPE_POLL) X(FILETYPE_PROCESS)
653808d9805SEd Schouten 	X(FILETYPE_REGULAR_FILE) X(FILETYPE_SHARED_MEMORY)
654808d9805SEd Schouten 	X(FILETYPE_SOCKET_DGRAM) X(FILETYPE_SOCKET_SEQPACKET)
655808d9805SEd Schouten 	X(FILETYPE_SOCKET_STREAM) X(FILETYPE_SYMBOLIC_LINK)
656808d9805SEd Schouten 	XEND
657808d9805SEd Schouten };
658808d9805SEd Schouten 
659808d9805SEd Schouten static struct xlat cloudabi_fsflags[] = {
660808d9805SEd Schouten 	X(FILESTAT_ATIM) X(FILESTAT_ATIM_NOW) X(FILESTAT_MTIM)
661808d9805SEd Schouten 	X(FILESTAT_MTIM_NOW) X(FILESTAT_SIZE)
662808d9805SEd Schouten 	XEND
663808d9805SEd Schouten };
664808d9805SEd Schouten 
665808d9805SEd Schouten static struct xlat cloudabi_mflags[] = {
666808d9805SEd Schouten 	X(MAP_ANON) X(MAP_FIXED) X(MAP_PRIVATE) X(MAP_SHARED)
667808d9805SEd Schouten 	XEND
668808d9805SEd Schouten };
669808d9805SEd Schouten 
670808d9805SEd Schouten static struct xlat cloudabi_mprot[] = {
671808d9805SEd Schouten 	X(PROT_EXEC) X(PROT_WRITE) X(PROT_READ)
672808d9805SEd Schouten 	XEND
673808d9805SEd Schouten };
674808d9805SEd Schouten 
675808d9805SEd Schouten static struct xlat cloudabi_msflags[] = {
676808d9805SEd Schouten 	X(MS_ASYNC) X(MS_INVALIDATE) X(MS_SYNC)
677808d9805SEd Schouten 	XEND
678808d9805SEd Schouten };
679808d9805SEd Schouten 
680808d9805SEd Schouten static struct xlat cloudabi_oflags[] = {
681808d9805SEd Schouten 	X(O_CREAT) X(O_DIRECTORY) X(O_EXCL) X(O_TRUNC)
682808d9805SEd Schouten 	XEND
683808d9805SEd Schouten };
684808d9805SEd Schouten 
685808d9805SEd Schouten static struct xlat cloudabi_sa_family[] = {
686808d9805SEd Schouten 	X(AF_UNSPEC) X(AF_INET) X(AF_INET6) X(AF_UNIX)
687808d9805SEd Schouten 	XEND
688808d9805SEd Schouten };
689808d9805SEd Schouten 
690808d9805SEd Schouten static struct xlat cloudabi_sdflags[] = {
691808d9805SEd Schouten 	X(SHUT_RD) X(SHUT_WR)
692808d9805SEd Schouten 	XEND
693808d9805SEd Schouten };
694808d9805SEd Schouten 
695808d9805SEd Schouten static struct xlat cloudabi_signal[] = {
696808d9805SEd Schouten 	X(SIGABRT) X(SIGALRM) X(SIGBUS) X(SIGCHLD) X(SIGCONT) X(SIGFPE)
697808d9805SEd Schouten 	X(SIGHUP) X(SIGILL) X(SIGINT) X(SIGKILL) X(SIGPIPE) X(SIGQUIT)
698808d9805SEd Schouten 	X(SIGSEGV) X(SIGSTOP) X(SIGSYS) X(SIGTERM) X(SIGTRAP) X(SIGTSTP)
699808d9805SEd Schouten 	X(SIGTTIN) X(SIGTTOU) X(SIGURG) X(SIGUSR1) X(SIGUSR2)
700808d9805SEd Schouten 	X(SIGVTALRM) X(SIGXCPU) X(SIGXFSZ)
701808d9805SEd Schouten 	XEND
702808d9805SEd Schouten };
703808d9805SEd Schouten 
704808d9805SEd Schouten static struct xlat cloudabi_ssflags[] = {
705808d9805SEd Schouten 	X(SOCKSTAT_CLEAR_ERROR)
706808d9805SEd Schouten 	XEND
707808d9805SEd Schouten };
708808d9805SEd Schouten 
709808d9805SEd Schouten static struct xlat cloudabi_ssstate[] = {
7101f3bbfd8SEd Schouten 	X(SOCKSTATE_ACCEPTCONN)
711808d9805SEd Schouten 	XEND
712808d9805SEd Schouten };
713808d9805SEd Schouten 
714808d9805SEd Schouten static struct xlat cloudabi_ulflags[] = {
715808d9805SEd Schouten 	X(UNLINK_REMOVEDIR)
716808d9805SEd Schouten 	XEND
717808d9805SEd Schouten };
718808d9805SEd Schouten 
719808d9805SEd Schouten static struct xlat cloudabi_whence[] = {
720808d9805SEd Schouten 	X(WHENCE_CUR) X(WHENCE_END) X(WHENCE_SET)
721808d9805SEd Schouten 	XEND
722808d9805SEd Schouten };
723808d9805SEd Schouten 
724808d9805SEd Schouten #undef X
725081e5c48SPav Lucistnik #undef XEND
726081e5c48SPav Lucistnik 
727d8984f48SDag-Erling Smørgrav /*
728d8984f48SDag-Erling Smørgrav  * Searches an xlat array for a value, and returns it if found.  Otherwise
729d8984f48SDag-Erling Smørgrav  * return a string representation.
730d8984f48SDag-Erling Smørgrav  */
731d8984f48SDag-Erling Smørgrav static const char *
732d8984f48SDag-Erling Smørgrav lookup(struct xlat *xlat, int val, int base)
733081e5c48SPav Lucistnik {
734081e5c48SPav Lucistnik 	static char tmp[16];
735d8984f48SDag-Erling Smørgrav 
736081e5c48SPav Lucistnik 	for (; xlat->str != NULL; xlat++)
737081e5c48SPav Lucistnik 		if (xlat->val == val)
738d8984f48SDag-Erling Smørgrav 			return (xlat->str);
739081e5c48SPav Lucistnik 	switch (base) {
740081e5c48SPav Lucistnik 		case 8:
741081e5c48SPav Lucistnik 			sprintf(tmp, "0%o", val);
742081e5c48SPav Lucistnik 			break;
743081e5c48SPav Lucistnik 		case 16:
744081e5c48SPav Lucistnik 			sprintf(tmp, "0x%x", val);
745081e5c48SPav Lucistnik 			break;
746081e5c48SPav Lucistnik 		case 10:
747081e5c48SPav Lucistnik 			sprintf(tmp, "%u", val);
748081e5c48SPav Lucistnik 			break;
749081e5c48SPav Lucistnik 		default:
750081e5c48SPav Lucistnik 			errx(1,"Unknown lookup base");
751081e5c48SPav Lucistnik 			break;
752081e5c48SPav Lucistnik 	}
753d8984f48SDag-Erling Smørgrav 	return (tmp);
754081e5c48SPav Lucistnik }
755081e5c48SPav Lucistnik 
7565d2d083cSXin LI static const char *
7575d2d083cSXin LI xlookup(struct xlat *xlat, int val)
758081e5c48SPav Lucistnik {
759d8984f48SDag-Erling Smørgrav 
760d8984f48SDag-Erling Smørgrav 	return (lookup(xlat, val, 16));
761081e5c48SPav Lucistnik }
762081e5c48SPav Lucistnik 
7634e3da534SJohn Baldwin /*
7644e3da534SJohn Baldwin  * Searches an xlat array containing bitfield values.  Remaining bits
7654e3da534SJohn Baldwin  * set after removing the known ones are printed at the end:
7664e3da534SJohn Baldwin  * IN|0x400.
7674e3da534SJohn Baldwin  */
768d8984f48SDag-Erling Smørgrav static char *
769d8984f48SDag-Erling Smørgrav xlookup_bits(struct xlat *xlat, int val)
770081e5c48SPav Lucistnik {
77194355cfdSAndrey Zonov 	int len, rem;
772081e5c48SPav Lucistnik 	static char str[512];
773081e5c48SPav Lucistnik 
77494355cfdSAndrey Zonov 	len = 0;
77594355cfdSAndrey Zonov 	rem = val;
776d8984f48SDag-Erling Smørgrav 	for (; xlat->str != NULL; xlat++) {
777d8984f48SDag-Erling Smørgrav 		if ((xlat->val & rem) == xlat->val) {
7784e3da534SJohn Baldwin 			/*
7794e3da534SJohn Baldwin 			 * Don't print the "all-bits-zero" string unless all
7804e3da534SJohn Baldwin 			 * bits are really zero.
7814e3da534SJohn Baldwin 			 */
782081e5c48SPav Lucistnik 			if (xlat->val == 0 && val != 0)
783081e5c48SPav Lucistnik 				continue;
784081e5c48SPav Lucistnik 			len += sprintf(str + len, "%s|", xlat->str);
785081e5c48SPav Lucistnik 			rem &= ~(xlat->val);
786081e5c48SPav Lucistnik 		}
787081e5c48SPav Lucistnik 	}
7884e3da534SJohn Baldwin 
7894e3da534SJohn Baldwin 	/*
7904e3da534SJohn Baldwin 	 * If we have leftover bits or didn't match anything, print
7914e3da534SJohn Baldwin 	 * the remainder.
7924e3da534SJohn Baldwin 	 */
793081e5c48SPav Lucistnik 	if (rem || len == 0)
794081e5c48SPav Lucistnik 		len += sprintf(str + len, "0x%x", rem);
795081e5c48SPav Lucistnik 	if (len && str[len - 1] == '|')
796081e5c48SPav Lucistnik 		len--;
797081e5c48SPav Lucistnik 	str[len] = 0;
798d8984f48SDag-Erling Smørgrav 	return (str);
799081e5c48SPav Lucistnik }
800081e5c48SPav Lucistnik 
8019289f547SJohn Baldwin static void
8029289f547SJohn Baldwin print_integer_arg(const char *(*decoder)(int), FILE *fp, int value)
8039289f547SJohn Baldwin {
8049289f547SJohn Baldwin 	const char *str;
8059289f547SJohn Baldwin 
8069289f547SJohn Baldwin 	str = decoder(value);
8079289f547SJohn Baldwin 	if (str != NULL)
8089289f547SJohn Baldwin 		fputs(str, fp);
8099289f547SJohn Baldwin 	else
8109289f547SJohn Baldwin 		fprintf(fp, "%d", value);
8119289f547SJohn Baldwin }
8129289f547SJohn Baldwin 
8139289f547SJohn Baldwin static void
8149289f547SJohn Baldwin print_mask_arg(bool (*decoder)(FILE *, int, int *), FILE *fp, int value)
8159289f547SJohn Baldwin {
8169289f547SJohn Baldwin 	int rem;
8179289f547SJohn Baldwin 
8189289f547SJohn Baldwin 	if (!decoder(fp, value, &rem))
8199289f547SJohn Baldwin 		fprintf(fp, "0x%x", rem);
8209289f547SJohn Baldwin 	else if (rem != 0)
8219289f547SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
8229289f547SJohn Baldwin }
8239289f547SJohn Baldwin 
824bed418c8SJohn Baldwin static void
825bed418c8SJohn Baldwin print_mask_arg32(bool (*decoder)(FILE *, uint32_t, uint32_t *), FILE *fp,
826bed418c8SJohn Baldwin     uint32_t value)
827bed418c8SJohn Baldwin {
828bed418c8SJohn Baldwin 	uint32_t rem;
829bed418c8SJohn Baldwin 
830bed418c8SJohn Baldwin 	if (!decoder(fp, value, &rem))
831bed418c8SJohn Baldwin 		fprintf(fp, "0x%x", rem);
832bed418c8SJohn Baldwin 	else if (rem != 0)
833bed418c8SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
834bed418c8SJohn Baldwin }
835bed418c8SJohn Baldwin 
836c05cc0d6SJohn Baldwin #ifndef __LP64__
837c05cc0d6SJohn Baldwin /*
838c05cc0d6SJohn Baldwin  * Add argument padding to subsequent system calls afater a Quad
839c05cc0d6SJohn Baldwin  * syscall arguments as needed.  This used to be done by hand in the
840c05cc0d6SJohn Baldwin  * decoded_syscalls table which was ugly and error prone.  It is
841c05cc0d6SJohn Baldwin  * simpler to do the fixup of offsets at initalization time than when
842c05cc0d6SJohn Baldwin  * decoding arguments.
843c05cc0d6SJohn Baldwin  */
844c05cc0d6SJohn Baldwin static void
845c05cc0d6SJohn Baldwin quad_fixup(struct syscall *sc)
846c05cc0d6SJohn Baldwin {
847c05cc0d6SJohn Baldwin 	int offset, prev;
848c05cc0d6SJohn Baldwin 	u_int i;
849c05cc0d6SJohn Baldwin 
850c05cc0d6SJohn Baldwin 	offset = 0;
851c05cc0d6SJohn Baldwin 	prev = -1;
852c05cc0d6SJohn Baldwin 	for (i = 0; i < sc->nargs; i++) {
853c05cc0d6SJohn Baldwin 		/* This arg type is a dummy that doesn't use offset. */
854c05cc0d6SJohn Baldwin 		if ((sc->args[i].type & ARG_MASK) == PipeFds)
855c05cc0d6SJohn Baldwin 			continue;
856c05cc0d6SJohn Baldwin 
857c05cc0d6SJohn Baldwin 		assert(prev < sc->args[i].offset);
858c05cc0d6SJohn Baldwin 		prev = sc->args[i].offset;
859c05cc0d6SJohn Baldwin 		sc->args[i].offset += offset;
860c05cc0d6SJohn Baldwin 		switch (sc->args[i].type & ARG_MASK) {
861c05cc0d6SJohn Baldwin 		case Quad:
862c05cc0d6SJohn Baldwin 		case QuadHex:
863c05cc0d6SJohn Baldwin #ifdef __powerpc__
864c05cc0d6SJohn Baldwin 			/*
865c05cc0d6SJohn Baldwin 			 * 64-bit arguments on 32-bit powerpc must be
866c05cc0d6SJohn Baldwin 			 * 64-bit aligned.  If the current offset is
867c05cc0d6SJohn Baldwin 			 * not aligned, the calling convention inserts
868c05cc0d6SJohn Baldwin 			 * a 32-bit pad argument that should be skipped.
869c05cc0d6SJohn Baldwin 			 */
870c05cc0d6SJohn Baldwin 			if (sc->args[i].offset % 2 == 1) {
871c05cc0d6SJohn Baldwin 				sc->args[i].offset++;
872c05cc0d6SJohn Baldwin 				offset++;
873c05cc0d6SJohn Baldwin 			}
874c05cc0d6SJohn Baldwin #endif
875c05cc0d6SJohn Baldwin 			offset++;
876c05cc0d6SJohn Baldwin 		default:
877c05cc0d6SJohn Baldwin 			break;
878c05cc0d6SJohn Baldwin 		}
879c05cc0d6SJohn Baldwin 	}
880c05cc0d6SJohn Baldwin }
881c05cc0d6SJohn Baldwin #endif
882c05cc0d6SJohn Baldwin 
8836c61b0f3SBryan Drewery void
8846c61b0f3SBryan Drewery init_syscalls(void)
8856c61b0f3SBryan Drewery {
8866c61b0f3SBryan Drewery 	struct syscall *sc;
8876c61b0f3SBryan Drewery 
8886c61b0f3SBryan Drewery 	STAILQ_INIT(&syscalls);
889c05cc0d6SJohn Baldwin 	for (sc = decoded_syscalls; sc->name != NULL; sc++) {
890c05cc0d6SJohn Baldwin #ifndef __LP64__
891c05cc0d6SJohn Baldwin 		quad_fixup(sc);
892c05cc0d6SJohn Baldwin #endif
8936c61b0f3SBryan Drewery 		STAILQ_INSERT_HEAD(&syscalls, sc, entries);
8946c61b0f3SBryan Drewery 	}
895c05cc0d6SJohn Baldwin }
8961175b23fSJohn Baldwin 
8971175b23fSJohn Baldwin static struct syscall *
8981175b23fSJohn Baldwin find_syscall(struct procabi *abi, u_int number)
8991175b23fSJohn Baldwin {
9001175b23fSJohn Baldwin 	struct extra_syscall *es;
9011175b23fSJohn Baldwin 
9021175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls))
9031175b23fSJohn Baldwin 		return (abi->syscalls[number]);
9041175b23fSJohn Baldwin 	STAILQ_FOREACH(es, &abi->extra_syscalls, entries) {
9051175b23fSJohn Baldwin 		if (es->number == number)
9061175b23fSJohn Baldwin 			return (es->sc);
9071175b23fSJohn Baldwin 	}
9081175b23fSJohn Baldwin 	return (NULL);
9091175b23fSJohn Baldwin }
9101175b23fSJohn Baldwin 
9111175b23fSJohn Baldwin static void
9121175b23fSJohn Baldwin add_syscall(struct procabi *abi, u_int number, struct syscall *sc)
9131175b23fSJohn Baldwin {
9141175b23fSJohn Baldwin 	struct extra_syscall *es;
9151175b23fSJohn Baldwin 
9161175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls)) {
9171175b23fSJohn Baldwin 		assert(abi->syscalls[number] == NULL);
9181175b23fSJohn Baldwin 		abi->syscalls[number] = sc;
9191175b23fSJohn Baldwin 	} else {
9201175b23fSJohn Baldwin 		es = malloc(sizeof(*es));
9211175b23fSJohn Baldwin 		es->sc = sc;
9221175b23fSJohn Baldwin 		es->number = number;
9231175b23fSJohn Baldwin 		STAILQ_INSERT_TAIL(&abi->extra_syscalls, es, entries);
9241175b23fSJohn Baldwin 	}
9251175b23fSJohn Baldwin }
9261175b23fSJohn Baldwin 
927bbeaf6c0SSean Eric Fagan /*
928bbeaf6c0SSean Eric Fagan  * If/when the list gets big, it might be desirable to do it
929bbeaf6c0SSean Eric Fagan  * as a hash table or binary search.
930bbeaf6c0SSean Eric Fagan  */
931bbeaf6c0SSean Eric Fagan struct syscall *
9321175b23fSJohn Baldwin get_syscall(struct threadinfo *t, u_int number, u_int nargs)
933d8984f48SDag-Erling Smørgrav {
93494355cfdSAndrey Zonov 	struct syscall *sc;
9351175b23fSJohn Baldwin 	const char *name;
9361175b23fSJohn Baldwin 	char *new_name;
9371175b23fSJohn Baldwin 	u_int i;
938bbeaf6c0SSean Eric Fagan 
9391175b23fSJohn Baldwin 	sc = find_syscall(t->proc->abi, number);
9401175b23fSJohn Baldwin 	if (sc != NULL)
941d8984f48SDag-Erling Smørgrav 		return (sc);
9426c61b0f3SBryan Drewery 
9431175b23fSJohn Baldwin 	name = sysdecode_syscallname(t->proc->abi->abi, number);
9441175b23fSJohn Baldwin 	if (name == NULL) {
9451175b23fSJohn Baldwin 		asprintf(&new_name, "#%d", number);
9461175b23fSJohn Baldwin 		name = new_name;
9471175b23fSJohn Baldwin 	} else
9481175b23fSJohn Baldwin 		new_name = NULL;
9491175b23fSJohn Baldwin 	STAILQ_FOREACH(sc, &syscalls, entries) {
9501175b23fSJohn Baldwin 		if (strcmp(name, sc->name) == 0) {
9511175b23fSJohn Baldwin 			add_syscall(t->proc->abi, number, sc);
9521175b23fSJohn Baldwin 			free(new_name);
9531175b23fSJohn Baldwin 			return (sc);
9541175b23fSJohn Baldwin 		}
9551175b23fSJohn Baldwin 	}
9561175b23fSJohn Baldwin 
9576c61b0f3SBryan Drewery 	/* It is unknown.  Add it into the list. */
9586c61b0f3SBryan Drewery #if DEBUG
9596c61b0f3SBryan Drewery 	fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
9606c61b0f3SBryan Drewery 	    nargs);
9616c61b0f3SBryan Drewery #endif
9626c61b0f3SBryan Drewery 
9636c61b0f3SBryan Drewery 	sc = calloc(1, sizeof(struct syscall));
9641175b23fSJohn Baldwin 	sc->name = name;
9651175b23fSJohn Baldwin 	if (new_name != NULL)
9661175b23fSJohn Baldwin 		sc->unknown = true;
9676c61b0f3SBryan Drewery 	sc->ret_type = 1;
9686c61b0f3SBryan Drewery 	sc->nargs = nargs;
9696c61b0f3SBryan Drewery 	for (i = 0; i < nargs; i++) {
9706c61b0f3SBryan Drewery 		sc->args[i].offset = i;
9716c61b0f3SBryan Drewery 		/* Treat all unknown arguments as LongHex. */
9726c61b0f3SBryan Drewery 		sc->args[i].type = LongHex;
973bbeaf6c0SSean Eric Fagan 	}
9746c61b0f3SBryan Drewery 	STAILQ_INSERT_HEAD(&syscalls, sc, entries);
9751175b23fSJohn Baldwin 	add_syscall(t->proc->abi, number, sc);
9766c61b0f3SBryan Drewery 
9776c61b0f3SBryan Drewery 	return (sc);
978bbeaf6c0SSean Eric Fagan }
979bbeaf6c0SSean Eric Fagan 
980bbeaf6c0SSean Eric Fagan /*
9819ddd1412SDag-Erling Smørgrav  * Copy a fixed amount of bytes from the process.
9829ddd1412SDag-Erling Smørgrav  */
9831be5d704SMark Murray static int
984be305c9cSAndrey Zonov get_struct(pid_t pid, void *offset, void *buf, int len)
985d8984f48SDag-Erling Smørgrav {
9865d2d083cSXin LI 	struct ptrace_io_desc iorequest;
9879ddd1412SDag-Erling Smørgrav 
9885d2d083cSXin LI 	iorequest.piod_op = PIOD_READ_D;
9895d2d083cSXin LI 	iorequest.piod_offs = offset;
9905d2d083cSXin LI 	iorequest.piod_addr = buf;
9915d2d083cSXin LI 	iorequest.piod_len = len;
9925d2d083cSXin LI 	if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0)
993d8984f48SDag-Erling Smørgrav 		return (-1);
994d8984f48SDag-Erling Smørgrav 	return (0);
9959ddd1412SDag-Erling Smørgrav }
9969ddd1412SDag-Erling Smørgrav 
9975d2d083cSXin LI #define	MAXSIZE		4096
998abb3f965SJohn Baldwin 
9999ddd1412SDag-Erling Smørgrav /*
1000bbeaf6c0SSean Eric Fagan  * Copy a string from the process.  Note that it is
1001bbeaf6c0SSean Eric Fagan  * expected to be a C string, but if max is set, it will
1002bbeaf6c0SSean Eric Fagan  * only get that much.
1003bbeaf6c0SSean Eric Fagan  */
10045d2d083cSXin LI static char *
1005abb3f965SJohn Baldwin get_string(pid_t pid, void *addr, int max)
1006d8984f48SDag-Erling Smørgrav {
10075d2d083cSXin LI 	struct ptrace_io_desc iorequest;
1008abb3f965SJohn Baldwin 	char *buf, *nbuf;
1009abb3f965SJohn Baldwin 	size_t offset, size, totalsize;
1010bbeaf6c0SSean Eric Fagan 
1011abb3f965SJohn Baldwin 	offset = 0;
1012abb3f965SJohn Baldwin 	if (max)
1013abb3f965SJohn Baldwin 		size = max + 1;
1014abb3f965SJohn Baldwin 	else {
1015abb3f965SJohn Baldwin 		/* Read up to the end of the current page. */
1016abb3f965SJohn Baldwin 		size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE);
1017abb3f965SJohn Baldwin 		if (size > MAXSIZE)
1018abb3f965SJohn Baldwin 			size = MAXSIZE;
1019abb3f965SJohn Baldwin 	}
1020abb3f965SJohn Baldwin 	totalsize = size;
10215d2d083cSXin LI 	buf = malloc(totalsize);
10225d2d083cSXin LI 	if (buf == NULL)
1023d8984f48SDag-Erling Smørgrav 		return (NULL);
10245d2d083cSXin LI 	for (;;) {
10255d2d083cSXin LI 		iorequest.piod_op = PIOD_READ_D;
1026abb3f965SJohn Baldwin 		iorequest.piod_offs = (char *)addr + offset;
1027abb3f965SJohn Baldwin 		iorequest.piod_addr = buf + offset;
10285d2d083cSXin LI 		iorequest.piod_len = size;
10295d2d083cSXin LI 		if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) {
10305d2d083cSXin LI 			free(buf);
1031d8984f48SDag-Erling Smørgrav 			return (NULL);
1032bbeaf6c0SSean Eric Fagan 		}
1033abb3f965SJohn Baldwin 		if (memchr(buf + offset, '\0', size) != NULL)
1034abb3f965SJohn Baldwin 			return (buf);
1035abb3f965SJohn Baldwin 		offset += size;
1036abb3f965SJohn Baldwin 		if (totalsize < MAXSIZE && max == 0) {
1037abb3f965SJohn Baldwin 			size = MAXSIZE - totalsize;
1038abb3f965SJohn Baldwin 			if (size > PAGE_SIZE)
1039abb3f965SJohn Baldwin 				size = PAGE_SIZE;
1040abb3f965SJohn Baldwin 			nbuf = realloc(buf, totalsize + size);
1041abb3f965SJohn Baldwin 			if (nbuf == NULL) {
1042abb3f965SJohn Baldwin 				buf[totalsize - 1] = '\0';
10434e92419dSMarcel Moolenaar 				return (buf);
1044bbeaf6c0SSean Eric Fagan 			}
1045abb3f965SJohn Baldwin 			buf = nbuf;
1046abb3f965SJohn Baldwin 			totalsize += size;
1047d8984f48SDag-Erling Smørgrav 		} else {
1048cdfc719cSJaakko Heinonen 			buf[totalsize - 1] = '\0';
1049d8984f48SDag-Erling Smørgrav 			return (buf);
10505d2d083cSXin LI 		}
10515d2d083cSXin LI 	}
10525d2d083cSXin LI }
1053bbeaf6c0SSean Eric Fagan 
10549289f547SJohn Baldwin static const char *
105534763d1cSJohn Baldwin strsig2(int sig)
105634763d1cSJohn Baldwin {
10579289f547SJohn Baldwin 	static char tmp[32];
10589289f547SJohn Baldwin 	const char *signame;
105934763d1cSJohn Baldwin 
10609289f547SJohn Baldwin 	signame = sysdecode_signal(sig);
10619289f547SJohn Baldwin 	if (signame == NULL) {
1062f083f689SJohn Baldwin 		snprintf(tmp, sizeof(tmp), "%d", sig);
10639289f547SJohn Baldwin 		signame = tmp;
1064f083f689SJohn Baldwin 	}
10659289f547SJohn Baldwin 	return (signame);
106634763d1cSJohn Baldwin }
1067bbeaf6c0SSean Eric Fagan 
1068c915ff03SJohn Baldwin static void
1069c915ff03SJohn Baldwin print_kevent(FILE *fp, struct kevent *ke, int input)
1070c915ff03SJohn Baldwin {
1071c915ff03SJohn Baldwin 
1072c915ff03SJohn Baldwin 	switch (ke->filter) {
1073c915ff03SJohn Baldwin 	case EVFILT_READ:
1074c915ff03SJohn Baldwin 	case EVFILT_WRITE:
1075c915ff03SJohn Baldwin 	case EVFILT_VNODE:
1076c915ff03SJohn Baldwin 	case EVFILT_PROC:
1077c915ff03SJohn Baldwin 	case EVFILT_TIMER:
1078c915ff03SJohn Baldwin 	case EVFILT_PROCDESC:
1079c915ff03SJohn Baldwin 		fprintf(fp, "%ju", (uintmax_t)ke->ident);
1080c915ff03SJohn Baldwin 		break;
1081c915ff03SJohn Baldwin 	case EVFILT_SIGNAL:
1082c915ff03SJohn Baldwin 		fputs(strsig2(ke->ident), fp);
1083c915ff03SJohn Baldwin 		break;
1084c915ff03SJohn Baldwin 	default:
1085c915ff03SJohn Baldwin 		fprintf(fp, "%p", (void *)ke->ident);
1086c915ff03SJohn Baldwin 	}
1087c915ff03SJohn Baldwin 	fprintf(fp, ",%s,%s,", xlookup(kevent_filters, ke->filter),
1088c915ff03SJohn Baldwin 	    xlookup_bits(kevent_flags, ke->flags));
1089c915ff03SJohn Baldwin 	switch (ke->filter) {
1090c915ff03SJohn Baldwin 	case EVFILT_READ:
1091c915ff03SJohn Baldwin 	case EVFILT_WRITE:
1092c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_rdwr_fflags, ke->fflags), fp);
1093c915ff03SJohn Baldwin 		break;
1094c915ff03SJohn Baldwin 	case EVFILT_VNODE:
1095c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_vnode_fflags, ke->fflags), fp);
1096c915ff03SJohn Baldwin 		break;
1097c915ff03SJohn Baldwin 	case EVFILT_PROC:
1098c915ff03SJohn Baldwin 	case EVFILT_PROCDESC:
1099c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_proc_fflags, ke->fflags), fp);
1100c915ff03SJohn Baldwin 		break;
1101c915ff03SJohn Baldwin 	case EVFILT_TIMER:
1102c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_timer_fflags, ke->fflags), fp);
1103c915ff03SJohn Baldwin 		break;
1104c915ff03SJohn Baldwin 	case EVFILT_USER: {
1105c915ff03SJohn Baldwin 		int ctrl, data;
1106c915ff03SJohn Baldwin 
1107c915ff03SJohn Baldwin 		ctrl = ke->fflags & NOTE_FFCTRLMASK;
1108c915ff03SJohn Baldwin 		data = ke->fflags & NOTE_FFLAGSMASK;
1109c915ff03SJohn Baldwin 		if (input) {
1110c915ff03SJohn Baldwin 			fputs(xlookup(kevent_user_ffctrl, ctrl), fp);
1111c915ff03SJohn Baldwin 			if (ke->fflags & NOTE_TRIGGER)
1112c915ff03SJohn Baldwin 				fputs("|NOTE_TRIGGER", fp);
1113c915ff03SJohn Baldwin 			if (data != 0)
1114c915ff03SJohn Baldwin 				fprintf(fp, "|%#x", data);
1115c915ff03SJohn Baldwin 		} else {
1116c915ff03SJohn Baldwin 			fprintf(fp, "%#x", data);
1117c915ff03SJohn Baldwin 		}
1118c915ff03SJohn Baldwin 		break;
1119c915ff03SJohn Baldwin 	}
1120c915ff03SJohn Baldwin 	default:
1121c915ff03SJohn Baldwin 		fprintf(fp, "%#x", ke->fflags);
1122c915ff03SJohn Baldwin 	}
1123c915ff03SJohn Baldwin 	fprintf(fp, ",%p,%p", (void *)ke->data, (void *)ke->udata);
1124c915ff03SJohn Baldwin }
1125c915ff03SJohn Baldwin 
1126195aef99SBryan Drewery static void
1127195aef99SBryan Drewery print_utrace(FILE *fp, void *utrace_addr, size_t len)
1128195aef99SBryan Drewery {
1129195aef99SBryan Drewery 	unsigned char *utrace_buffer;
1130195aef99SBryan Drewery 
1131195aef99SBryan Drewery 	fprintf(fp, "{ ");
1132d6fb4894SJohn Baldwin 	if (sysdecode_utrace(fp, utrace_addr, len)) {
1133195aef99SBryan Drewery 		fprintf(fp, " }");
1134195aef99SBryan Drewery 		return;
1135195aef99SBryan Drewery 	}
1136195aef99SBryan Drewery 
1137195aef99SBryan Drewery 	utrace_buffer = utrace_addr;
1138195aef99SBryan Drewery 	fprintf(fp, "%zu:", len);
1139195aef99SBryan Drewery 	while (len--)
1140195aef99SBryan Drewery 		fprintf(fp, " %02x", *utrace_buffer++);
1141195aef99SBryan Drewery 	fprintf(fp, " }");
1142195aef99SBryan Drewery }
1143195aef99SBryan Drewery 
1144bbeaf6c0SSean Eric Fagan /*
1145bbeaf6c0SSean Eric Fagan  * Converts a syscall argument into a string.  Said string is
11464e3da534SJohn Baldwin  * allocated via malloc(), so needs to be free()'d.  sc is
1147bbeaf6c0SSean Eric Fagan  * a pointer to the syscall description (see above); args is
1148bbeaf6c0SSean Eric Fagan  * an array of all of the system call arguments.
1149bbeaf6c0SSean Eric Fagan  */
1150bbeaf6c0SSean Eric Fagan char *
11512b75c8adSJohn Baldwin print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
115294355cfdSAndrey Zonov     struct trussinfo *trussinfo)
1153d8984f48SDag-Erling Smørgrav {
1154f083f689SJohn Baldwin 	FILE *fp;
115594355cfdSAndrey Zonov 	char *tmp;
1156f083f689SJohn Baldwin 	size_t tmplen;
115794355cfdSAndrey Zonov 	pid_t pid;
1158d8984f48SDag-Erling Smørgrav 
1159f083f689SJohn Baldwin 	fp = open_memstream(&tmp, &tmplen);
11602b75c8adSJohn Baldwin 	pid = trussinfo->curthread->proc->pid;
1161bbeaf6c0SSean Eric Fagan 	switch (sc->type & ARG_MASK) {
1162bbeaf6c0SSean Eric Fagan 	case Hex:
1163f083f689SJohn Baldwin 		fprintf(fp, "0x%x", (int)args[sc->offset]);
1164bbeaf6c0SSean Eric Fagan 		break;
1165bbeaf6c0SSean Eric Fagan 	case Octal:
1166f083f689SJohn Baldwin 		fprintf(fp, "0%o", (int)args[sc->offset]);
1167bbeaf6c0SSean Eric Fagan 		break;
1168bbeaf6c0SSean Eric Fagan 	case Int:
1169f083f689SJohn Baldwin 		fprintf(fp, "%d", (int)args[sc->offset]);
1170bbeaf6c0SSean Eric Fagan 		break;
1171808d9805SEd Schouten 	case UInt:
1172808d9805SEd Schouten 		fprintf(fp, "%u", (unsigned int)args[sc->offset]);
1173808d9805SEd Schouten 		break;
1174fdb5bf37SJohn Baldwin 	case LongHex:
1175f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
1176fdb5bf37SJohn Baldwin 		break;
1177b289a8d7SJohn Baldwin 	case Long:
1178f083f689SJohn Baldwin 		fprintf(fp, "%ld", args[sc->offset]);
1179b289a8d7SJohn Baldwin 		break;
1180e261fb2aSJohn Baldwin 	case Sizet:
1181e261fb2aSJohn Baldwin 		fprintf(fp, "%zu", (size_t)args[sc->offset]);
1182e261fb2aSJohn Baldwin 		break;
1183d8984f48SDag-Erling Smørgrav 	case Name: {
1184081e5c48SPav Lucistnik 		/* NULL-terminated string. */
1185bbeaf6c0SSean Eric Fagan 		char *tmp2;
11864e3da534SJohn Baldwin 
11875d2d083cSXin LI 		tmp2 = get_string(pid, (void*)args[sc->offset], 0);
1188f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
1189bbeaf6c0SSean Eric Fagan 		free(tmp2);
1190bbeaf6c0SSean Eric Fagan 		break;
1191d8984f48SDag-Erling Smørgrav 	}
1192d8984f48SDag-Erling Smørgrav 	case BinString: {
11934e3da534SJohn Baldwin 		/*
11944e3da534SJohn Baldwin 		 * Binary block of data that might have printable characters.
11954e3da534SJohn Baldwin 		 * XXX If type|OUT, assume that the length is the syscall's
11964e3da534SJohn Baldwin 		 * return value.  Otherwise, assume that the length of the block
11974e3da534SJohn Baldwin 		 * is in the next syscall argument.
11984e3da534SJohn Baldwin 		 */
1199081e5c48SPav Lucistnik 		int max_string = trussinfo->strsize;
1200081e5c48SPav Lucistnik 		char tmp2[max_string + 1], *tmp3;
1201081e5c48SPav Lucistnik 		int len;
1202081e5c48SPav Lucistnik 		int truncated = 0;
1203081e5c48SPav Lucistnik 
1204081e5c48SPav Lucistnik 		if (sc->type & OUT)
12052b75c8adSJohn Baldwin 			len = retval[0];
1206081e5c48SPav Lucistnik 		else
1207081e5c48SPav Lucistnik 			len = args[sc->offset + 1];
1208081e5c48SPav Lucistnik 
12094e3da534SJohn Baldwin 		/*
12104e3da534SJohn Baldwin 		 * Don't print more than max_string characters, to avoid word
12114e3da534SJohn Baldwin 		 * wrap.  If we have to truncate put some ... after the string.
1212081e5c48SPav Lucistnik 		 */
1213081e5c48SPav Lucistnik 		if (len > max_string) {
1214081e5c48SPav Lucistnik 			len = max_string;
1215081e5c48SPav Lucistnik 			truncated = 1;
1216081e5c48SPav Lucistnik 		}
121794355cfdSAndrey Zonov 		if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len)
121894355cfdSAndrey Zonov 		    != -1) {
1219081e5c48SPav Lucistnik 			tmp3 = malloc(len * 4 + 1);
1220081e5c48SPav Lucistnik 			while (len) {
122194355cfdSAndrey Zonov 				if (strvisx(tmp3, tmp2, len,
122294355cfdSAndrey Zonov 				    VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
1223081e5c48SPav Lucistnik 					break;
1224081e5c48SPav Lucistnik 				len--;
1225081e5c48SPav Lucistnik 				truncated = 1;
122680c7cc1cSPedro F. Giffuni 			}
1227f083f689SJohn Baldwin 			fprintf(fp, "\"%s\"%s", tmp3, truncated ?
122894355cfdSAndrey Zonov 			    "..." : "");
1229081e5c48SPav Lucistnik 			free(tmp3);
1230d8984f48SDag-Erling Smørgrav 		} else {
1231f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1232081e5c48SPav Lucistnik 		}
1233081e5c48SPav Lucistnik 		break;
1234d8984f48SDag-Erling Smørgrav 	}
123568055893SJohn Baldwin 	case ExecArgs:
123668055893SJohn Baldwin 	case ExecEnv:
1237d8984f48SDag-Erling Smørgrav 	case StringArray: {
1238890843c1SJohn Baldwin 		uintptr_t addr;
1239890843c1SJohn Baldwin 		union {
1240890843c1SJohn Baldwin 			char *strarray[0];
1241890843c1SJohn Baldwin 			char buf[PAGE_SIZE];
1242890843c1SJohn Baldwin 		} u;
12439897b203SMatthew N. Dodd 		char *string;
1244890843c1SJohn Baldwin 		size_t len;
12452b75c8adSJohn Baldwin 		u_int first, i;
12469897b203SMatthew N. Dodd 
1247890843c1SJohn Baldwin 		/*
124868055893SJohn Baldwin 		 * Only parse argv[] and environment arrays from exec calls
124968055893SJohn Baldwin 		 * if requested.
125068055893SJohn Baldwin 		 */
125168055893SJohn Baldwin 		if (((sc->type & ARG_MASK) == ExecArgs &&
125268055893SJohn Baldwin 		    (trussinfo->flags & EXECVEARGS) == 0) ||
125368055893SJohn Baldwin 		    ((sc->type & ARG_MASK) == ExecEnv &&
125468055893SJohn Baldwin 		    (trussinfo->flags & EXECVEENVS) == 0)) {
125568055893SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
125668055893SJohn Baldwin 			break;
125768055893SJohn Baldwin 		}
125868055893SJohn Baldwin 
125968055893SJohn Baldwin 		/*
1260890843c1SJohn Baldwin 		 * Read a page of pointers at a time.  Punt if the top-level
1261890843c1SJohn Baldwin 		 * pointer is not aligned.  Note that the first read is of
1262890843c1SJohn Baldwin 		 * a partial page.
1263890843c1SJohn Baldwin 		 */
1264890843c1SJohn Baldwin 		addr = args[sc->offset];
1265890843c1SJohn Baldwin 		if (addr % sizeof(char *) != 0) {
1266890843c1SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1267890843c1SJohn Baldwin 			break;
12689897b203SMatthew N. Dodd 		}
12699897b203SMatthew N. Dodd 
1270890843c1SJohn Baldwin 		len = PAGE_SIZE - (addr & PAGE_MASK);
1271890843c1SJohn Baldwin 		if (get_struct(pid, (void *)addr, u.buf, len) == -1) {
1272890843c1SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1273890843c1SJohn Baldwin 			break;
12749897b203SMatthew N. Dodd 		}
1275890843c1SJohn Baldwin 
1276890843c1SJohn Baldwin 		fputc('[', fp);
1277890843c1SJohn Baldwin 		first = 1;
1278890843c1SJohn Baldwin 		i = 0;
1279890843c1SJohn Baldwin 		while (u.strarray[i] != NULL) {
1280890843c1SJohn Baldwin 			string = get_string(pid, u.strarray[i], 0);
1281890843c1SJohn Baldwin 			fprintf(fp, "%s \"%s\"", first ? "" : ",", string);
1282890843c1SJohn Baldwin 			free(string);
1283890843c1SJohn Baldwin 			first = 0;
1284890843c1SJohn Baldwin 
1285890843c1SJohn Baldwin 			i++;
1286890843c1SJohn Baldwin 			if (i == len / sizeof(char *)) {
1287890843c1SJohn Baldwin 				addr += len;
1288890843c1SJohn Baldwin 				len = PAGE_SIZE;
1289890843c1SJohn Baldwin 				if (get_struct(pid, (void *)addr, u.buf, len) ==
1290890843c1SJohn Baldwin 				    -1) {
1291890843c1SJohn Baldwin 					fprintf(fp, ", <inval>");
1292890843c1SJohn Baldwin 					break;
1293890843c1SJohn Baldwin 				}
1294890843c1SJohn Baldwin 				i = 0;
1295890843c1SJohn Baldwin 			}
1296890843c1SJohn Baldwin 		}
1297890843c1SJohn Baldwin 		fputs(" ]", fp);
12989897b203SMatthew N. Dodd 		break;
1299d8984f48SDag-Erling Smørgrav 	}
130010aeefc9SMarcel Moolenaar #ifdef __LP64__
130110aeefc9SMarcel Moolenaar 	case Quad:
130272df19e7SJohn Baldwin 		fprintf(fp, "%ld", args[sc->offset]);
130372df19e7SJohn Baldwin 		break;
130472df19e7SJohn Baldwin 	case QuadHex:
1305f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
130610aeefc9SMarcel Moolenaar 		break;
130710aeefc9SMarcel Moolenaar #else
130872df19e7SJohn Baldwin 	case Quad:
130972df19e7SJohn Baldwin 	case QuadHex: {
131010aeefc9SMarcel Moolenaar 		unsigned long long ll;
13114e3da534SJohn Baldwin 
13122b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
13132b75c8adSJohn Baldwin 		ll = (unsigned long long)args[sc->offset + 1] << 32 |
13142b75c8adSJohn Baldwin 		    args[sc->offset];
13152b75c8adSJohn Baldwin #else
13162b75c8adSJohn Baldwin 		ll = (unsigned long long)args[sc->offset] << 32 |
13172b75c8adSJohn Baldwin 		    args[sc->offset + 1];
13182b75c8adSJohn Baldwin #endif
131972df19e7SJohn Baldwin 		if ((sc->type & ARG_MASK) == Quad)
132072df19e7SJohn Baldwin 			fprintf(fp, "%lld", ll);
132172df19e7SJohn Baldwin 		else
1322f083f689SJohn Baldwin 			fprintf(fp, "0x%llx", ll);
1323bbeaf6c0SSean Eric Fagan 		break;
1324bbeaf6c0SSean Eric Fagan 	}
132510aeefc9SMarcel Moolenaar #endif
1326bbeaf6c0SSean Eric Fagan 	case Ptr:
1327f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
1328bbeaf6c0SSean Eric Fagan 		break;
1329d8984f48SDag-Erling Smørgrav 	case Readlinkres: {
13302bae4eb3SAlfred Perlstein 		char *tmp2;
13314e3da534SJohn Baldwin 
13322b75c8adSJohn Baldwin 		if (retval[0] == -1)
13332bae4eb3SAlfred Perlstein 			break;
13342b75c8adSJohn Baldwin 		tmp2 = get_string(pid, (void*)args[sc->offset], retval[0]);
1335f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
13362bae4eb3SAlfred Perlstein 		free(tmp2);
13372bae4eb3SAlfred Perlstein 		break;
1338d8984f48SDag-Erling Smørgrav 	}
1339d8984f48SDag-Erling Smørgrav 	case Ioctl: {
13404e3da534SJohn Baldwin 		const char *temp;
13414e3da534SJohn Baldwin 		unsigned long cmd;
13424e3da534SJohn Baldwin 
13434e3da534SJohn Baldwin 		cmd = args[sc->offset];
1344265e5898SJohn Baldwin 		temp = sysdecode_ioctlname(cmd);
134594355cfdSAndrey Zonov 		if (temp)
1346f083f689SJohn Baldwin 			fputs(temp, fp);
134794355cfdSAndrey Zonov 		else {
1348f083f689SJohn Baldwin 			fprintf(fp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
13494e3da534SJohn Baldwin 			    cmd, cmd & IOC_OUT ? "R" : "",
13504e3da534SJohn Baldwin 			    cmd & IOC_IN ? "W" : "", IOCGROUP(cmd),
13514e3da534SJohn Baldwin 			    isprint(IOCGROUP(cmd)) ? (char)IOCGROUP(cmd) : '?',
13524e3da534SJohn Baldwin 			    cmd & 0xFF, IOCPARM_LEN(cmd));
1353081e5c48SPav Lucistnik 		}
1354081e5c48SPav Lucistnik 		break;
1355d8984f48SDag-Erling Smørgrav 	}
1356d8984f48SDag-Erling Smørgrav 	case Timespec: {
1357e45a5a0dSDavid Malone 		struct timespec ts;
13584e3da534SJohn Baldwin 
135994355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &ts,
136094355cfdSAndrey Zonov 		    sizeof(ts)) != -1)
1361a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%09ld }", (intmax_t)ts.tv_sec,
136294355cfdSAndrey Zonov 			    ts.tv_nsec);
1363e45a5a0dSDavid Malone 		else
1364f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1365e45a5a0dSDavid Malone 		break;
1366d8984f48SDag-Erling Smørgrav 	}
13677d897327SJohn Baldwin 	case Timespec2: {
13687d897327SJohn Baldwin 		struct timespec ts[2];
13697d897327SJohn Baldwin 		const char *sep;
13707d897327SJohn Baldwin 		unsigned int i;
13717d897327SJohn Baldwin 
13727d897327SJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts))
13737d897327SJohn Baldwin 		    != -1) {
13741e2ec671SJohn Baldwin 			fputs("{ ", fp);
13757d897327SJohn Baldwin 			sep = "";
13767d897327SJohn Baldwin 			for (i = 0; i < nitems(ts); i++) {
13777d897327SJohn Baldwin 				fputs(sep, fp);
13787d897327SJohn Baldwin 				sep = ", ";
13797d897327SJohn Baldwin 				switch (ts[i].tv_nsec) {
13807d897327SJohn Baldwin 				case UTIME_NOW:
13817d897327SJohn Baldwin 					fprintf(fp, "UTIME_NOW");
13827d897327SJohn Baldwin 					break;
13837d897327SJohn Baldwin 				case UTIME_OMIT:
13847d897327SJohn Baldwin 					fprintf(fp, "UTIME_OMIT");
13857d897327SJohn Baldwin 					break;
13867d897327SJohn Baldwin 				default:
1387a1436773SJohn Baldwin 					fprintf(fp, "%jd.%09ld",
1388a1436773SJohn Baldwin 					    (intmax_t)ts[i].tv_sec,
1389a1436773SJohn Baldwin 					    ts[i].tv_nsec);
13907d897327SJohn Baldwin 					break;
13917d897327SJohn Baldwin 				}
13927d897327SJohn Baldwin 			}
13931e2ec671SJohn Baldwin 			fputs(" }", fp);
13947d897327SJohn Baldwin 		} else
1395f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
13967d897327SJohn Baldwin 		break;
13977d897327SJohn Baldwin 	}
1398d8984f48SDag-Erling Smørgrav 	case Timeval: {
1399e45a5a0dSDavid Malone 		struct timeval tv;
14004e3da534SJohn Baldwin 
140194355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
140294355cfdSAndrey Zonov 		    != -1)
1403a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld }", (intmax_t)tv.tv_sec,
140494355cfdSAndrey Zonov 			    tv.tv_usec);
1405081e5c48SPav Lucistnik 		else
1406f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1407081e5c48SPav Lucistnik 		break;
1408d8984f48SDag-Erling Smørgrav 	}
1409d8984f48SDag-Erling Smørgrav 	case Timeval2: {
1410081e5c48SPav Lucistnik 		struct timeval tv[2];
14114e3da534SJohn Baldwin 
141294355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
141394355cfdSAndrey Zonov 		    != -1)
1414a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1415a1436773SJohn Baldwin 			    (intmax_t)tv[0].tv_sec, tv[0].tv_usec,
1416a1436773SJohn Baldwin 			    (intmax_t)tv[1].tv_sec, tv[1].tv_usec);
1417e45a5a0dSDavid Malone 		else
1418f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1419e45a5a0dSDavid Malone 		break;
1420d8984f48SDag-Erling Smørgrav 	}
1421d8984f48SDag-Erling Smørgrav 	case Itimerval: {
1422e45a5a0dSDavid Malone 		struct itimerval itv;
14234e3da534SJohn Baldwin 
142494355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &itv,
142594355cfdSAndrey Zonov 		    sizeof(itv)) != -1)
1426a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1427a1436773SJohn Baldwin 			    (intmax_t)itv.it_interval.tv_sec,
1428081e5c48SPav Lucistnik 			    itv.it_interval.tv_usec,
1429a1436773SJohn Baldwin 			    (intmax_t)itv.it_value.tv_sec,
1430081e5c48SPav Lucistnik 			    itv.it_value.tv_usec);
1431e45a5a0dSDavid Malone 		else
1432f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1433e45a5a0dSDavid Malone 		break;
1434d8984f48SDag-Erling Smørgrav 	}
14351c99a22aSSteven Hartland 	case LinuxSockArgs:
14361c99a22aSSteven Hartland 	{
14371c99a22aSSteven Hartland 		struct linux_socketcall_args largs;
14384e3da534SJohn Baldwin 
14391c99a22aSSteven Hartland 		if (get_struct(pid, (void *)args[sc->offset], (void *)&largs,
1440fb7eabb0SJohn Baldwin 		    sizeof(largs)) != -1)
1441f083f689SJohn Baldwin 			fprintf(fp, "{ %s, 0x%lx }",
1442fb7eabb0SJohn Baldwin 			    lookup(linux_socketcall_ops, largs.what, 10),
14430a46af44SJohn Baldwin 			    (long unsigned int)largs.args);
1444fb7eabb0SJohn Baldwin 		else
1445f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
14461c99a22aSSteven Hartland 		break;
14471c99a22aSSteven Hartland 	}
1448d8984f48SDag-Erling Smørgrav 	case Pollfd: {
1449e45a5a0dSDavid Malone 		/*
145094355cfdSAndrey Zonov 		 * XXX: A Pollfd argument expects the /next/ syscall argument
145194355cfdSAndrey Zonov 		 * to be the number of fds in the array. This matches the poll
145294355cfdSAndrey Zonov 		 * syscall.
1453e45a5a0dSDavid Malone 		 */
1454e45a5a0dSDavid Malone 		struct pollfd *pfd;
1455e45a5a0dSDavid Malone 		int numfds = args[sc->offset + 1];
1456f083f689SJohn Baldwin 		size_t bytes = sizeof(struct pollfd) * numfds;
1457f083f689SJohn Baldwin 		int i;
1458e45a5a0dSDavid Malone 
1459e45a5a0dSDavid Malone 		if ((pfd = malloc(bytes)) == NULL)
1460f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for pollfd array",
146194355cfdSAndrey Zonov 			    bytes);
146294355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], pfd, bytes)
146394355cfdSAndrey Zonov 		    != -1) {
1464f083f689SJohn Baldwin 			fputs("{", fp);
1465e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1466f083f689SJohn Baldwin 				fprintf(fp, " %d/%s", pfd[i].fd,
1467081e5c48SPav Lucistnik 				    xlookup_bits(poll_flags, pfd[i].events));
1468e45a5a0dSDavid Malone 			}
1469f083f689SJohn Baldwin 			fputs(" }", fp);
1470d8984f48SDag-Erling Smørgrav 		} else {
1471f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1472e45a5a0dSDavid Malone 		}
1473d8984f48SDag-Erling Smørgrav 		free(pfd);
1474e45a5a0dSDavid Malone 		break;
1475d8984f48SDag-Erling Smørgrav 	}
1476d8984f48SDag-Erling Smørgrav 	case Fd_set: {
1477e45a5a0dSDavid Malone 		/*
147894355cfdSAndrey Zonov 		 * XXX: A Fd_set argument expects the /first/ syscall argument
147994355cfdSAndrey Zonov 		 * to be the number of fds in the array.  This matches the
148094355cfdSAndrey Zonov 		 * select syscall.
1481e45a5a0dSDavid Malone 		 */
1482e45a5a0dSDavid Malone 		fd_set *fds;
1483e45a5a0dSDavid Malone 		int numfds = args[0];
1484f083f689SJohn Baldwin 		size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
1485f083f689SJohn Baldwin 		int i;
1486e45a5a0dSDavid Malone 
1487e45a5a0dSDavid Malone 		if ((fds = malloc(bytes)) == NULL)
1488f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for fd_set array",
148994355cfdSAndrey Zonov 			    bytes);
149094355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], fds, bytes)
149194355cfdSAndrey Zonov 		    != -1) {
1492f083f689SJohn Baldwin 			fputs("{", fp);
1493e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1494f083f689SJohn Baldwin 				if (FD_ISSET(i, fds))
1495f083f689SJohn Baldwin 					fprintf(fp, " %d", i);
1496e45a5a0dSDavid Malone 			}
1497f083f689SJohn Baldwin 			fputs(" }", fp);
149894355cfdSAndrey Zonov 		} else
1499f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1500d8984f48SDag-Erling Smørgrav 		free(fds);
1501e45a5a0dSDavid Malone 		break;
1502d8984f48SDag-Erling Smørgrav 	}
150334763d1cSJohn Baldwin 	case Signal:
1504f083f689SJohn Baldwin 		fputs(strsig2(args[sc->offset]), fp);
1505f0ebbc29SDag-Erling Smørgrav 		break;
1506d8984f48SDag-Erling Smørgrav 	case Sigset: {
1507081e5c48SPav Lucistnik 		long sig;
1508081e5c48SPav Lucistnik 		sigset_t ss;
1509f083f689SJohn Baldwin 		int i, first;
1510081e5c48SPav Lucistnik 
1511081e5c48SPav Lucistnik 		sig = args[sc->offset];
151294355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
151394355cfdSAndrey Zonov 		    sizeof(ss)) == -1) {
1514f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1515081e5c48SPav Lucistnik 			break;
1516081e5c48SPav Lucistnik 		}
1517f083f689SJohn Baldwin 		fputs("{ ", fp);
1518f083f689SJohn Baldwin 		first = 1;
1519d8984f48SDag-Erling Smørgrav 		for (i = 1; i < sys_nsig; i++) {
152034763d1cSJohn Baldwin 			if (sigismember(&ss, i)) {
1521f083f689SJohn Baldwin 				fprintf(fp, "%s%s", !first ? "|" : "",
15229289f547SJohn Baldwin 				    strsig2(i));
1523f083f689SJohn Baldwin 				first = 0;
152434763d1cSJohn Baldwin 			}
1525081e5c48SPav Lucistnik 		}
1526f083f689SJohn Baldwin 		if (!first)
1527f083f689SJohn Baldwin 			fputc(' ', fp);
1528f083f689SJohn Baldwin 		fputc('}', fp);
1529081e5c48SPav Lucistnik 		break;
1530d8984f48SDag-Erling Smørgrav 	}
15319289f547SJohn Baldwin 	case Sigprocmask:
15329289f547SJohn Baldwin 		print_integer_arg(sysdecode_sigprocmask_how, fp,
15339289f547SJohn Baldwin 		    args[sc->offset]);
1534894b8f7aSAlfred Perlstein 		break;
15359289f547SJohn Baldwin 	case Fcntlflag:
15364e3da534SJohn Baldwin 		/* XXX: Output depends on the value of the previous argument. */
15379289f547SJohn Baldwin 		if (sysdecode_fcntl_arg_p(args[sc->offset - 1]))
15389289f547SJohn Baldwin 			sysdecode_fcntl_arg(fp, args[sc->offset - 1],
15399289f547SJohn Baldwin 			    args[sc->offset], 16);
1540081e5c48SPav Lucistnik 		break;
1541081e5c48SPav Lucistnik 	case Open:
15429289f547SJohn Baldwin 		print_mask_arg(sysdecode_open_flags, fp, args[sc->offset]);
1543081e5c48SPav Lucistnik 		break;
1544081e5c48SPav Lucistnik 	case Fcntl:
15459289f547SJohn Baldwin 		print_integer_arg(sysdecode_fcntl_cmd, fp, args[sc->offset]);
1546081e5c48SPav Lucistnik 		break;
1547894b8f7aSAlfred Perlstein 	case Mprot:
15489289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_prot, fp, args[sc->offset]);
1549894b8f7aSAlfred Perlstein 		break;
15509289f547SJohn Baldwin 	case Mmapflags:
15519289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_flags, fp, args[sc->offset]);
1552894b8f7aSAlfred Perlstein 		break;
1553fde3a7d1SAlfred Perlstein 	case Whence:
15549289f547SJohn Baldwin 		print_integer_arg(sysdecode_whence, fp, args[sc->offset]);
1555081e5c48SPav Lucistnik 		break;
1556081e5c48SPav Lucistnik 	case Sockdomain:
15579289f547SJohn Baldwin 		print_integer_arg(sysdecode_socketdomain, fp, args[sc->offset]);
1558081e5c48SPav Lucistnik 		break;
15599289f547SJohn Baldwin 	case Socktype:
15609289f547SJohn Baldwin 		print_mask_arg(sysdecode_socket_type, fp, args[sc->offset]);
1561081e5c48SPav Lucistnik 		break;
1562081e5c48SPav Lucistnik 	case Shutdown:
15639289f547SJohn Baldwin 		print_integer_arg(sysdecode_shutdown_how, fp, args[sc->offset]);
1564081e5c48SPav Lucistnik 		break;
1565081e5c48SPav Lucistnik 	case Resource:
15669289f547SJohn Baldwin 		print_integer_arg(sysdecode_rlimit, fp, args[sc->offset]);
1567081e5c48SPav Lucistnik 		break;
1568081e5c48SPav Lucistnik 	case Pathconf:
1569f083f689SJohn Baldwin 		fputs(xlookup(pathconf_arg, args[sc->offset]), fp);
1570fde3a7d1SAlfred Perlstein 		break;
15719e1db66eSMark Johnston 	case Rforkflags:
15729289f547SJohn Baldwin 		print_mask_arg(sysdecode_rfork_flags, fp, args[sc->offset]);
15739e1db66eSMark Johnston 		break;
1574d8984f48SDag-Erling Smørgrav 	case Sockaddr: {
15759ddd1412SDag-Erling Smørgrav 		char addr[64];
15761be5d704SMark Murray 		struct sockaddr_in *lsin;
15771be5d704SMark Murray 		struct sockaddr_in6 *lsin6;
1578dec17687SBrian Feldman 		struct sockaddr_un *sun;
1579dec17687SBrian Feldman 		struct sockaddr *sa;
158066917ca9SJohn Baldwin 		socklen_t len;
1581dec17687SBrian Feldman 		u_char *q;
15829ddd1412SDag-Erling Smørgrav 
1583a7a08c7eSMarcel Moolenaar 		if (args[sc->offset] == 0) {
1584f083f689SJohn Baldwin 			fputs("NULL", fp);
1585a7a08c7eSMarcel Moolenaar 			break;
1586a7a08c7eSMarcel Moolenaar 		}
1587a7a08c7eSMarcel Moolenaar 
15886a656761SAlfred Perlstein 		/*
158966917ca9SJohn Baldwin 		 * Extract the address length from the next argument.  If
159066917ca9SJohn Baldwin 		 * this is an output sockaddr (OUT is set), then the
159166917ca9SJohn Baldwin 		 * next argument is a pointer to a socklen_t.  Otherwise
159266917ca9SJohn Baldwin 		 * the next argument contains a socklen_t by value.
15936a656761SAlfred Perlstein 		 */
159466917ca9SJohn Baldwin 		if (sc->type & OUT) {
159566917ca9SJohn Baldwin 			if (get_struct(pid, (void *)args[sc->offset + 1],
159666917ca9SJohn Baldwin 			    &len, sizeof(len)) == -1) {
159766917ca9SJohn Baldwin 				fprintf(fp, "0x%lx", args[sc->offset]);
15986a656761SAlfred Perlstein 				break;
15996a656761SAlfred Perlstein 			}
160066917ca9SJohn Baldwin 		} else
160166917ca9SJohn Baldwin 			len = args[sc->offset + 1];
160266917ca9SJohn Baldwin 
160366917ca9SJohn Baldwin 		/* If the length is too small, just bail. */
160466917ca9SJohn Baldwin 		if (len < sizeof(*sa)) {
1605f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1606f083f689SJohn Baldwin 			break;
16079ddd1412SDag-Erling Smørgrav 		}
1608dec17687SBrian Feldman 
160966917ca9SJohn Baldwin 		sa = calloc(1, len);
161066917ca9SJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], sa, len) == -1) {
161166917ca9SJohn Baldwin 			free(sa);
161266917ca9SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
161366917ca9SJohn Baldwin 			break;
161466917ca9SJohn Baldwin 		}
161566917ca9SJohn Baldwin 
161666917ca9SJohn Baldwin 		switch (sa->sa_family) {
1617dec17687SBrian Feldman 		case AF_INET:
161866917ca9SJohn Baldwin 			if (len < sizeof(*lsin))
161966917ca9SJohn Baldwin 				goto sockaddr_short;
162066917ca9SJohn Baldwin 			lsin = (struct sockaddr_in *)(void *)sa;
16214e3da534SJohn Baldwin 			inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr));
1622f083f689SJohn Baldwin 			fprintf(fp, "{ AF_INET %s:%d }", addr,
162394355cfdSAndrey Zonov 			    htons(lsin->sin_port));
1624dec17687SBrian Feldman 			break;
1625dec17687SBrian Feldman 		case AF_INET6:
162666917ca9SJohn Baldwin 			if (len < sizeof(*lsin6))
162766917ca9SJohn Baldwin 				goto sockaddr_short;
162866917ca9SJohn Baldwin 			lsin6 = (struct sockaddr_in6 *)(void *)sa;
162994355cfdSAndrey Zonov 			inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
16304e3da534SJohn Baldwin 			    sizeof(addr));
1631f083f689SJohn Baldwin 			fprintf(fp, "{ AF_INET6 [%s]:%d }", addr,
163294355cfdSAndrey Zonov 			    htons(lsin6->sin6_port));
1633dec17687SBrian Feldman 			break;
1634dec17687SBrian Feldman 		case AF_UNIX:
163566917ca9SJohn Baldwin 			sun = (struct sockaddr_un *)sa;
163666917ca9SJohn Baldwin 			fprintf(fp, "{ AF_UNIX \"%.*s\" }",
163766917ca9SJohn Baldwin 			    (int)(len - offsetof(struct sockaddr_un, sun_path)),
163866917ca9SJohn Baldwin 			    sun->sun_path);
1639dec17687SBrian Feldman 			break;
1640dec17687SBrian Feldman 		default:
164166917ca9SJohn Baldwin 		sockaddr_short:
1642f083f689SJohn Baldwin 			fprintf(fp,
1643f083f689SJohn Baldwin 			    "{ sa_len = %d, sa_family = %d, sa_data = {",
1644f083f689SJohn Baldwin 			    (int)sa->sa_len, (int)sa->sa_family);
1645f083f689SJohn Baldwin 			for (q = (u_char *)sa->sa_data;
164666917ca9SJohn Baldwin 			     q < (u_char *)sa + len; q++)
1647f083f689SJohn Baldwin 				fprintf(fp, "%s 0x%02x",
1648f083f689SJohn Baldwin 				    q == (u_char *)sa->sa_data ? "" : ",",
1649f083f689SJohn Baldwin 				    *q);
1650f083f689SJohn Baldwin 			fputs(" } }", fp);
1651dec17687SBrian Feldman 		}
165266917ca9SJohn Baldwin 		free(sa);
16539ddd1412SDag-Erling Smørgrav 		break;
1654d8984f48SDag-Erling Smørgrav 	}
1655d8984f48SDag-Erling Smørgrav 	case Sigaction: {
1656e45a5a0dSDavid Malone 		struct sigaction sa;
1657e45a5a0dSDavid Malone 
165894355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa))
165994355cfdSAndrey Zonov 		    != -1) {
1660f083f689SJohn Baldwin 			fputs("{ ", fp);
1661e45a5a0dSDavid Malone 			if (sa.sa_handler == SIG_DFL)
1662f083f689SJohn Baldwin 				fputs("SIG_DFL", fp);
1663e45a5a0dSDavid Malone 			else if (sa.sa_handler == SIG_IGN)
1664f083f689SJohn Baldwin 				fputs("SIG_IGN", fp);
1665e45a5a0dSDavid Malone 			else
1666f083f689SJohn Baldwin 				fprintf(fp, "%p", sa.sa_handler);
1667f083f689SJohn Baldwin 			fprintf(fp, " %s ss_t }",
1668081e5c48SPav Lucistnik 			    xlookup_bits(sigaction_flags, sa.sa_flags));
166994355cfdSAndrey Zonov 		} else
1670f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1671e45a5a0dSDavid Malone 		break;
1672d8984f48SDag-Erling Smørgrav 	}
1673d8984f48SDag-Erling Smørgrav 	case Kevent: {
1674081e5c48SPav Lucistnik 		/*
16754e3da534SJohn Baldwin 		 * XXX XXX: The size of the array is determined by either the
1676081e5c48SPav Lucistnik 		 * next syscall argument, or by the syscall return value,
1677081e5c48SPav Lucistnik 		 * depending on which argument number we are.  This matches the
1678081e5c48SPav Lucistnik 		 * kevent syscall, but luckily that's the only syscall that uses
1679081e5c48SPav Lucistnik 		 * them.
1680081e5c48SPav Lucistnik 		 */
1681081e5c48SPav Lucistnik 		struct kevent *ke;
1682081e5c48SPav Lucistnik 		int numevents = -1;
1683f083f689SJohn Baldwin 		size_t bytes;
1684f083f689SJohn Baldwin 		int i;
1685081e5c48SPav Lucistnik 
1686081e5c48SPav Lucistnik 		if (sc->offset == 1)
1687081e5c48SPav Lucistnik 			numevents = args[sc->offset+1];
16882b75c8adSJohn Baldwin 		else if (sc->offset == 3 && retval[0] != -1)
16892b75c8adSJohn Baldwin 			numevents = retval[0];
1690081e5c48SPav Lucistnik 
1691f083f689SJohn Baldwin 		if (numevents >= 0) {
1692081e5c48SPav Lucistnik 			bytes = sizeof(struct kevent) * numevents;
1693081e5c48SPav Lucistnik 			if ((ke = malloc(bytes)) == NULL)
1694f083f689SJohn Baldwin 				err(1,
1695f083f689SJohn Baldwin 				    "Cannot malloc %zu bytes for kevent array",
169694355cfdSAndrey Zonov 				    bytes);
1697f083f689SJohn Baldwin 		} else
1698f083f689SJohn Baldwin 			ke = NULL;
169994355cfdSAndrey Zonov 		if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset],
170094355cfdSAndrey Zonov 		    ke, bytes) != -1) {
1701f083f689SJohn Baldwin 			fputc('{', fp);
1702c915ff03SJohn Baldwin 			for (i = 0; i < numevents; i++) {
1703c915ff03SJohn Baldwin 				fputc(' ', fp);
1704c915ff03SJohn Baldwin 				print_kevent(fp, &ke[i], sc->offset == 1);
1705c915ff03SJohn Baldwin 			}
1706f083f689SJohn Baldwin 			fputs(" }", fp);
1707d8984f48SDag-Erling Smørgrav 		} else {
1708f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1709081e5c48SPav Lucistnik 		}
1710d8984f48SDag-Erling Smørgrav 		free(ke);
1711081e5c48SPav Lucistnik 		break;
1712d8984f48SDag-Erling Smørgrav 	}
1713d8984f48SDag-Erling Smørgrav 	case Stat: {
1714081e5c48SPav Lucistnik 		struct stat st;
17154e3da534SJohn Baldwin 
171694355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st))
171794355cfdSAndrey Zonov 		    != -1) {
1718081e5c48SPav Lucistnik 			char mode[12];
17194e3da534SJohn Baldwin 
1720081e5c48SPav Lucistnik 			strmode(st.st_mode, mode);
1721f083f689SJohn Baldwin 			fprintf(fp,
1722b38fbc2eSJohn Baldwin 			    "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode,
1723b38fbc2eSJohn Baldwin 			    (uintmax_t)st.st_ino, (intmax_t)st.st_size,
172494355cfdSAndrey Zonov 			    (long)st.st_blksize);
1725d8984f48SDag-Erling Smørgrav 		} else {
1726f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1727081e5c48SPav Lucistnik 		}
1728081e5c48SPav Lucistnik 		break;
1729d8984f48SDag-Erling Smørgrav 	}
1730a776866bSBryan Drewery 	case StatFs: {
1731a776866bSBryan Drewery 		unsigned int i;
1732a776866bSBryan Drewery 		struct statfs buf;
17330a71c082SBryan Drewery 
1734a776866bSBryan Drewery 		if (get_struct(pid, (void *)args[sc->offset], &buf,
1735a776866bSBryan Drewery 		    sizeof(buf)) != -1) {
1736a776866bSBryan Drewery 			char fsid[17];
1737a776866bSBryan Drewery 
1738a776866bSBryan Drewery 			bzero(fsid, sizeof(fsid));
1739a776866bSBryan Drewery 			if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) {
1740a776866bSBryan Drewery 			        for (i = 0; i < sizeof(buf.f_fsid); i++)
1741a776866bSBryan Drewery 					snprintf(&fsid[i*2],
1742a776866bSBryan Drewery 					    sizeof(fsid) - (i*2), "%02x",
1743a776866bSBryan Drewery 					    ((u_char *)&buf.f_fsid)[i]);
1744a776866bSBryan Drewery 			}
1745a776866bSBryan Drewery 			fprintf(fp,
1746a776866bSBryan Drewery 			    "{ fstypename=%s,mntonname=%s,mntfromname=%s,"
1747a776866bSBryan Drewery 			    "fsid=%s }", buf.f_fstypename, buf.f_mntonname,
1748a776866bSBryan Drewery 			    buf.f_mntfromname, fsid);
1749a776866bSBryan Drewery 		} else
1750a776866bSBryan Drewery 			fprintf(fp, "0x%lx", args[sc->offset]);
1751a776866bSBryan Drewery 		break;
1752a776866bSBryan Drewery 	}
1753a776866bSBryan Drewery 
1754d8984f48SDag-Erling Smørgrav 	case Rusage: {
1755081e5c48SPav Lucistnik 		struct rusage ru;
17564e3da534SJohn Baldwin 
175794355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru))
175894355cfdSAndrey Zonov 		    != -1) {
1759f083f689SJohn Baldwin 			fprintf(fp,
1760a1436773SJohn Baldwin 			    "{ u=%jd.%06ld,s=%jd.%06ld,in=%ld,out=%ld }",
1761a1436773SJohn Baldwin 			    (intmax_t)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
1762a1436773SJohn Baldwin 			    (intmax_t)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
1763081e5c48SPav Lucistnik 			    ru.ru_inblock, ru.ru_oublock);
176494355cfdSAndrey Zonov 		} else
1765f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1766081e5c48SPav Lucistnik 		break;
1767d8984f48SDag-Erling Smørgrav 	}
1768d8984f48SDag-Erling Smørgrav 	case Rlimit: {
1769081e5c48SPav Lucistnik 		struct rlimit rl;
17704e3da534SJohn Baldwin 
177194355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl))
177294355cfdSAndrey Zonov 		    != -1) {
1773f083f689SJohn Baldwin 			fprintf(fp, "{ cur=%ju,max=%ju }",
1774081e5c48SPav Lucistnik 			    rl.rlim_cur, rl.rlim_max);
177594355cfdSAndrey Zonov 		} else
1776f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1777081e5c48SPav Lucistnik 		break;
1778d8984f48SDag-Erling Smørgrav 	}
177934763d1cSJohn Baldwin 	case ExitStatus: {
178034763d1cSJohn Baldwin 		int status;
1781f083f689SJohn Baldwin 
178234763d1cSJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], &status,
178334763d1cSJohn Baldwin 		    sizeof(status)) != -1) {
1784f083f689SJohn Baldwin 			fputs("{ ", fp);
178534763d1cSJohn Baldwin 			if (WIFCONTINUED(status))
1786f083f689SJohn Baldwin 				fputs("CONTINUED", fp);
178734763d1cSJohn Baldwin 			else if (WIFEXITED(status))
1788f083f689SJohn Baldwin 				fprintf(fp, "EXITED,val=%d",
178934763d1cSJohn Baldwin 				    WEXITSTATUS(status));
179034763d1cSJohn Baldwin 			else if (WIFSIGNALED(status))
1791f083f689SJohn Baldwin 				fprintf(fp, "SIGNALED,sig=%s%s",
1792f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)),
179334763d1cSJohn Baldwin 				    WCOREDUMP(status) ? ",cored" : "");
179434763d1cSJohn Baldwin 			else
1795f083f689SJohn Baldwin 				fprintf(fp, "STOPPED,sig=%s",
1796f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)));
1797f083f689SJohn Baldwin 			fputs(" }", fp);
179834763d1cSJohn Baldwin 		} else
1799f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
180034763d1cSJohn Baldwin 		break;
180134763d1cSJohn Baldwin 	}
180234763d1cSJohn Baldwin 	case Waitoptions:
18039289f547SJohn Baldwin 		print_mask_arg(sysdecode_wait6_options, fp, args[sc->offset]);
180434763d1cSJohn Baldwin 		break;
180534763d1cSJohn Baldwin 	case Idtype:
18069289f547SJohn Baldwin 		print_integer_arg(sysdecode_idtype, fp, args[sc->offset]);
180734763d1cSJohn Baldwin 		break;
180855648840SJohn Baldwin 	case Procctl:
18099289f547SJohn Baldwin 		print_integer_arg(sysdecode_procctl_cmd, fp, args[sc->offset]);
181055648840SJohn Baldwin 		break;
1811fdb5bf37SJohn Baldwin 	case Umtxop:
18129289f547SJohn Baldwin 		print_integer_arg(sysdecode_umtx_op, fp, args[sc->offset]);
1813fdb5bf37SJohn Baldwin 		break;
18147d897327SJohn Baldwin 	case Atfd:
18159289f547SJohn Baldwin 		print_integer_arg(sysdecode_atfd, fp, args[sc->offset]);
18167d897327SJohn Baldwin 		break;
18177d897327SJohn Baldwin 	case Atflags:
1818f083f689SJohn Baldwin 		fputs(xlookup_bits(at_flags, args[sc->offset]), fp);
18197d897327SJohn Baldwin 		break;
18207d897327SJohn Baldwin 	case Accessmode:
18219289f547SJohn Baldwin 		print_mask_arg(sysdecode_access_mode, fp, args[sc->offset]);
18227d897327SJohn Baldwin 		break;
1823b289a8d7SJohn Baldwin 	case Sysarch:
1824f083f689SJohn Baldwin 		fputs(xlookup(sysarch_ops, args[sc->offset]), fp);
1825b289a8d7SJohn Baldwin 		break;
18262b75c8adSJohn Baldwin 	case PipeFds:
18272b75c8adSJohn Baldwin 		/*
18282b75c8adSJohn Baldwin 		 * The pipe() system call in the kernel returns its
18292b75c8adSJohn Baldwin 		 * two file descriptors via return values.  However,
18302b75c8adSJohn Baldwin 		 * the interface exposed by libc is that pipe()
18312b75c8adSJohn Baldwin 		 * accepts a pointer to an array of descriptors.
18322b75c8adSJohn Baldwin 		 * Format the output to match the libc API by printing
18332b75c8adSJohn Baldwin 		 * the returned file descriptors as a fake argument.
18342b75c8adSJohn Baldwin 		 *
18352b75c8adSJohn Baldwin 		 * Overwrite the first retval to signal a successful
18362b75c8adSJohn Baldwin 		 * return as well.
18372b75c8adSJohn Baldwin 		 */
18382b75c8adSJohn Baldwin 		fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]);
18392b75c8adSJohn Baldwin 		retval[0] = 0;
18402b75c8adSJohn Baldwin 		break;
1841195aef99SBryan Drewery 	case Utrace: {
1842195aef99SBryan Drewery 		size_t len;
1843195aef99SBryan Drewery 		void *utrace_addr;
1844195aef99SBryan Drewery 
1845195aef99SBryan Drewery 		len = args[sc->offset + 1];
1846195aef99SBryan Drewery 		utrace_addr = calloc(1, len);
1847195aef99SBryan Drewery 		if (get_struct(pid, (void *)args[sc->offset],
1848195aef99SBryan Drewery 		    (void *)utrace_addr, len) != -1)
1849195aef99SBryan Drewery 			print_utrace(fp, utrace_addr, len);
1850195aef99SBryan Drewery 		else
1851195aef99SBryan Drewery 			fprintf(fp, "0x%lx", args[sc->offset]);
1852195aef99SBryan Drewery 		free(utrace_addr);
1853195aef99SBryan Drewery 		break;
1854195aef99SBryan Drewery 	}
1855808d9805SEd Schouten 	case IntArray: {
1856808d9805SEd Schouten 		int descriptors[16];
1857808d9805SEd Schouten 		unsigned long i, ndescriptors;
1858808d9805SEd Schouten 		bool truncated;
1859808d9805SEd Schouten 
1860808d9805SEd Schouten 		ndescriptors = args[sc->offset + 1];
1861808d9805SEd Schouten 		truncated = false;
1862808d9805SEd Schouten 		if (ndescriptors > nitems(descriptors)) {
1863808d9805SEd Schouten 			ndescriptors = nitems(descriptors);
1864808d9805SEd Schouten 			truncated = true;
1865808d9805SEd Schouten 		}
1866808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset],
1867808d9805SEd Schouten 		    descriptors, ndescriptors * sizeof(descriptors[0])) != -1) {
1868808d9805SEd Schouten 			fprintf(fp, "{");
1869808d9805SEd Schouten 			for (i = 0; i < ndescriptors; i++)
1870808d9805SEd Schouten 				fprintf(fp, i == 0 ? " %d" : ", %d",
1871808d9805SEd Schouten 				    descriptors[i]);
1872808d9805SEd Schouten 			fprintf(fp, truncated ? ", ... }" : " }");
1873808d9805SEd Schouten 		} else
1874808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1875808d9805SEd Schouten 		break;
1876808d9805SEd Schouten 	}
18779289f547SJohn Baldwin 	case Pipe2:
18789289f547SJohn Baldwin 		print_mask_arg(sysdecode_pipe2_flags, fp, args[sc->offset]);
18799289f547SJohn Baldwin 		break;
1880bed418c8SJohn Baldwin 	case CapFcntlRights: {
1881bed418c8SJohn Baldwin 		uint32_t rights;
1882bed418c8SJohn Baldwin 
1883bed418c8SJohn Baldwin 		if (sc->type & OUT) {
1884bed418c8SJohn Baldwin 			if (get_struct(pid, (void *)args[sc->offset], &rights,
1885bed418c8SJohn Baldwin 			    sizeof(rights)) == -1) {
1886bed418c8SJohn Baldwin 				fprintf(fp, "0x%lx", args[sc->offset]);
1887bed418c8SJohn Baldwin 				break;
1888bed418c8SJohn Baldwin 			}
1889bed418c8SJohn Baldwin 		} else
1890bed418c8SJohn Baldwin 			rights = args[sc->offset];
1891bed418c8SJohn Baldwin 		print_mask_arg32(sysdecode_cap_fcntlrights, fp, rights);
1892bed418c8SJohn Baldwin 		break;
1893bed418c8SJohn Baldwin 	}
1894d2a97485SJohn Baldwin 	case Fadvice:
1895d2a97485SJohn Baldwin 		print_integer_arg(sysdecode_fadvice, fp, args[sc->offset]);
1896d2a97485SJohn Baldwin 		break;
189727459358SJohn Baldwin 	case FileFlags: {
189827459358SJohn Baldwin 		fflags_t rem;
189927459358SJohn Baldwin 
190027459358SJohn Baldwin 		if (!sysdecode_fileflags(fp, args[sc->offset], &rem))
190127459358SJohn Baldwin 			fprintf(fp, "0x%x", rem);
190227459358SJohn Baldwin 		else if (rem != 0)
190327459358SJohn Baldwin 			fprintf(fp, "|0x%x", rem);
190427459358SJohn Baldwin 		break;
190527459358SJohn Baldwin 	}
1906dd92181fSJohn Baldwin 	case Flockop:
1907dd92181fSJohn Baldwin 		print_mask_arg(sysdecode_flock_operation, fp, args[sc->offset]);
1908dd92181fSJohn Baldwin 		break;
1909ab43bedcSJohn Baldwin 	case Getfsstatmode:
1910ab43bedcSJohn Baldwin 		print_integer_arg(sysdecode_getfsstat_mode, fp,
1911ab43bedcSJohn Baldwin 		    args[sc->offset]);
1912ab43bedcSJohn Baldwin 		break;
191394e854c5SJohn Baldwin 	case Kldsymcmd:
191494e854c5SJohn Baldwin 		print_integer_arg(sysdecode_kldsym_cmd, fp, args[sc->offset]);
191594e854c5SJohn Baldwin 		break;
191694e854c5SJohn Baldwin 	case Kldunloadflags:
191794e854c5SJohn Baldwin 		print_integer_arg(sysdecode_kldunload_flags, fp,
191894e854c5SJohn Baldwin 		    args[sc->offset]);
191994e854c5SJohn Baldwin 		break;
192098fdbeecSJohn Baldwin 	case Madvice:
192198fdbeecSJohn Baldwin 		print_integer_arg(sysdecode_madvice, fp, args[sc->offset]);
192298fdbeecSJohn Baldwin 		break;
192358227c60SMichael Tuexen 	case Socklent:
192458227c60SMichael Tuexen 		fprintf(fp, "%u", (socklen_t)args[sc->offset]);
192558227c60SMichael Tuexen 		break;
1926ecac235bSMichael Tuexen 	case Sockprotocol: {
1927ecac235bSMichael Tuexen 		int protocol;
1928ecac235bSMichael Tuexen 
1929ecac235bSMichael Tuexen 		protocol = args[sc->offset];
1930ecac235bSMichael Tuexen 		if (protocol == 0) {
1931ecac235bSMichael Tuexen 			fputs("0", fp);
1932ecac235bSMichael Tuexen 		} else {
1933ecac235bSMichael Tuexen 			print_integer_arg(sysdecode_ipproto, fp, protocol);
1934ecac235bSMichael Tuexen 		}
1935ecac235bSMichael Tuexen 		break;
1936ecac235bSMichael Tuexen 	}
1937*832af457SMichael Tuexen 	case Sockoptlevel:
1938*832af457SMichael Tuexen 		print_integer_arg(sysdecode_sockopt_level, fp,
1939*832af457SMichael Tuexen 		    args[sc->offset]);
1940*832af457SMichael Tuexen 		break;
1941*832af457SMichael Tuexen 	case Sockoptname: {
1942*832af457SMichael Tuexen 		const char *temp;
1943*832af457SMichael Tuexen 		int level, name;
1944*832af457SMichael Tuexen 
1945*832af457SMichael Tuexen 		level = args[sc->offset - 1];
1946*832af457SMichael Tuexen 		name = args[sc->offset];
1947*832af457SMichael Tuexen 		temp = sysdecode_sockopt_name(level, name);
1948*832af457SMichael Tuexen 		if (temp) {
1949*832af457SMichael Tuexen 			fputs(temp, fp);
1950*832af457SMichael Tuexen 		} else {
1951*832af457SMichael Tuexen 			fprintf(fp, "%d", name);
1952*832af457SMichael Tuexen 		}
1953*832af457SMichael Tuexen 		break;
1954*832af457SMichael Tuexen 	}
1955808d9805SEd Schouten 
1956808d9805SEd Schouten 	case CloudABIAdvice:
1957808d9805SEd Schouten 		fputs(xlookup(cloudabi_advice, args[sc->offset]), fp);
1958808d9805SEd Schouten 		break;
1959808d9805SEd Schouten 	case CloudABIClockID:
1960808d9805SEd Schouten 		fputs(xlookup(cloudabi_clockid, args[sc->offset]), fp);
1961808d9805SEd Schouten 		break;
1962808d9805SEd Schouten 	case ClouduABIFDSFlags:
1963808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_fdsflags, args[sc->offset]), fp);
1964808d9805SEd Schouten 		break;
1965808d9805SEd Schouten 	case CloudABIFDStat: {
1966808d9805SEd Schouten 		cloudabi_fdstat_t fds;
1967808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &fds, sizeof(fds))
1968808d9805SEd Schouten 		    != -1) {
1969808d9805SEd Schouten 			fprintf(fp, "{ %s, ",
1970808d9805SEd Schouten 			    xlookup(cloudabi_filetype, fds.fs_filetype));
1971808d9805SEd Schouten 			fprintf(fp, "%s, ... }",
1972808d9805SEd Schouten 			    xlookup_bits(cloudabi_fdflags, fds.fs_flags));
1973808d9805SEd Schouten 		} else
1974808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1975808d9805SEd Schouten 		break;
1976808d9805SEd Schouten 	}
1977808d9805SEd Schouten 	case CloudABIFileStat: {
1978808d9805SEd Schouten 		cloudabi_filestat_t fsb;
1979808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &fsb, sizeof(fsb))
1980808d9805SEd Schouten 		    != -1)
19819ba32307SJohn Baldwin 			fprintf(fp, "{ %s, %ju }",
1982808d9805SEd Schouten 			    xlookup(cloudabi_filetype, fsb.st_filetype),
19839ba32307SJohn Baldwin 			    (uintmax_t)fsb.st_size);
1984808d9805SEd Schouten 		else
1985808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1986808d9805SEd Schouten 		break;
1987808d9805SEd Schouten 	}
1988808d9805SEd Schouten 	case CloudABIFileType:
1989808d9805SEd Schouten 		fputs(xlookup(cloudabi_filetype, args[sc->offset]), fp);
1990808d9805SEd Schouten 		break;
1991808d9805SEd Schouten 	case CloudABIFSFlags:
1992808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_fsflags, args[sc->offset]), fp);
1993808d9805SEd Schouten 		break;
1994808d9805SEd Schouten 	case CloudABILookup:
1995808d9805SEd Schouten 		if ((args[sc->offset] & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) != 0)
1996808d9805SEd Schouten 			fprintf(fp, "%d|LOOKUP_SYMLINK_FOLLOW",
1997808d9805SEd Schouten 			    (int)args[sc->offset]);
1998808d9805SEd Schouten 		else
1999808d9805SEd Schouten 			fprintf(fp, "%d", (int)args[sc->offset]);
2000808d9805SEd Schouten 		break;
2001808d9805SEd Schouten 	case CloudABIMFlags:
2002808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_mflags, args[sc->offset]), fp);
2003808d9805SEd Schouten 		break;
2004808d9805SEd Schouten 	case CloudABIMProt:
2005808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_mprot, args[sc->offset]), fp);
2006808d9805SEd Schouten 		break;
2007808d9805SEd Schouten 	case CloudABIMSFlags:
2008808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_msflags, args[sc->offset]), fp);
2009808d9805SEd Schouten 		break;
2010808d9805SEd Schouten 	case CloudABIOFlags:
2011808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_oflags, args[sc->offset]), fp);
2012808d9805SEd Schouten 		break;
2013808d9805SEd Schouten 	case CloudABISDFlags:
2014808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_sdflags, args[sc->offset]), fp);
2015808d9805SEd Schouten 		break;
2016808d9805SEd Schouten 	case CloudABISignal:
2017808d9805SEd Schouten 		fputs(xlookup(cloudabi_signal, args[sc->offset]), fp);
2018808d9805SEd Schouten 		break;
2019808d9805SEd Schouten 	case CloudABISockStat: {
2020808d9805SEd Schouten 		cloudabi_sockstat_t ss;
2021808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &ss, sizeof(ss))
2022808d9805SEd Schouten 		    != -1) {
2023808d9805SEd Schouten 			fprintf(fp, "{ %s, ", xlookup(
2024808d9805SEd Schouten 			    cloudabi_sa_family, ss.ss_sockname.sa_family));
2025808d9805SEd Schouten 			fprintf(fp, "%s, ", xlookup(
2026808d9805SEd Schouten 			    cloudabi_sa_family, ss.ss_peername.sa_family));
2027808d9805SEd Schouten 			fprintf(fp, "%s, ", xlookup(
2028808d9805SEd Schouten 			    cloudabi_errno, ss.ss_error));
2029808d9805SEd Schouten 			fprintf(fp, "%s }", xlookup_bits(
2030808d9805SEd Schouten 			    cloudabi_ssstate, ss.ss_state));
2031808d9805SEd Schouten 		} else
2032808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
2033808d9805SEd Schouten 		break;
2034808d9805SEd Schouten 	}
2035808d9805SEd Schouten 	case CloudABISSFlags:
2036808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_ssflags, args[sc->offset]), fp);
2037808d9805SEd Schouten 		break;
2038808d9805SEd Schouten 	case CloudABITimestamp:
2039808d9805SEd Schouten 		fprintf(fp, "%lu.%09lus", args[sc->offset] / 1000000000,
2040808d9805SEd Schouten 		    args[sc->offset] % 1000000000);
2041808d9805SEd Schouten 		break;
2042808d9805SEd Schouten 	case CloudABIULFlags:
2043808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_ulflags, args[sc->offset]), fp);
2044808d9805SEd Schouten 		break;
2045808d9805SEd Schouten 	case CloudABIWhence:
2046808d9805SEd Schouten 		fputs(xlookup(cloudabi_whence, args[sc->offset]), fp);
2047808d9805SEd Schouten 		break;
2048808d9805SEd Schouten 
2049081e5c48SPav Lucistnik 	default:
2050081e5c48SPav Lucistnik 		errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
2051bbeaf6c0SSean Eric Fagan 	}
2052f083f689SJohn Baldwin 	fclose(fp);
2053d8984f48SDag-Erling Smørgrav 	return (tmp);
2054bbeaf6c0SSean Eric Fagan }
2055bbeaf6c0SSean Eric Fagan 
2056bbeaf6c0SSean Eric Fagan /*
205700ddbdf2SJohn Baldwin  * Print (to outfile) the system call and its arguments.
2058bbeaf6c0SSean Eric Fagan  */
2059bbeaf6c0SSean Eric Fagan void
206000ddbdf2SJohn Baldwin print_syscall(struct trussinfo *trussinfo)
2061d8984f48SDag-Erling Smørgrav {
206200ddbdf2SJohn Baldwin 	struct threadinfo *t;
206300ddbdf2SJohn Baldwin 	const char *name;
206400ddbdf2SJohn Baldwin 	char **s_args;
206500ddbdf2SJohn Baldwin 	int i, len, nargs;
20660d0bd00eSMatthew N. Dodd 
206700ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
2068c03bfcc8SMatthew N. Dodd 
20691175b23fSJohn Baldwin 	name = t->cs.sc->name;
207000ddbdf2SJohn Baldwin 	nargs = t->cs.nargs;
207100ddbdf2SJohn Baldwin 	s_args = t->cs.s_args;
20720d0bd00eSMatthew N. Dodd 
2073d70876fdSJohn Baldwin 	len = print_line_prefix(trussinfo);
2074ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, "%s(", name);
2075c03bfcc8SMatthew N. Dodd 
2076bbeaf6c0SSean Eric Fagan 	for (i = 0; i < nargs; i++) {
207700ddbdf2SJohn Baldwin 		if (s_args[i] != NULL)
2078ec0bed25SMatthew N. Dodd 			len += fprintf(trussinfo->outfile, "%s", s_args[i]);
2079bbeaf6c0SSean Eric Fagan 		else
208094355cfdSAndrey Zonov 			len += fprintf(trussinfo->outfile,
208194355cfdSAndrey Zonov 			    "<missing argument>");
208294355cfdSAndrey Zonov 		len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ?
208394355cfdSAndrey Zonov 		    "," : "");
2084bbeaf6c0SSean Eric Fagan 	}
2085ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, ")");
20866cb533feSSean Eric Fagan 	for (i = 0; i < 6 - (len / 8); i++)
2087ec0bed25SMatthew N. Dodd 		fprintf(trussinfo->outfile, "\t");
20886cb533feSSean Eric Fagan }
20896cb533feSSean Eric Fagan 
20906cb533feSSean Eric Fagan void
209100ddbdf2SJohn Baldwin print_syscall_ret(struct trussinfo *trussinfo, int errorp, long *retval)
20921bcb5f5aSMarcel Moolenaar {
2093ee3b0f6eSDiomidis Spinellis 	struct timespec timediff;
209400ddbdf2SJohn Baldwin 	struct threadinfo *t;
209500ddbdf2SJohn Baldwin 	struct syscall *sc;
2096287b96ddSJohn Baldwin 	int error;
2097ee3b0f6eSDiomidis Spinellis 
209800ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
209900ddbdf2SJohn Baldwin 	sc = t->cs.sc;
2100ee3b0f6eSDiomidis Spinellis 	if (trussinfo->flags & COUNTONLY) {
210100ddbdf2SJohn Baldwin 		timespecsubt(&t->after, &t->before, &timediff);
2102d9dcc463SXin LI 		timespecadd(&sc->time, &timediff, &sc->time);
2103ee3b0f6eSDiomidis Spinellis 		sc->ncalls++;
2104ee3b0f6eSDiomidis Spinellis 		if (errorp)
2105ee3b0f6eSDiomidis Spinellis 			sc->nerror++;
2106ee3b0f6eSDiomidis Spinellis 		return;
2107ee3b0f6eSDiomidis Spinellis 	}
2108d8984f48SDag-Erling Smørgrav 
210900ddbdf2SJohn Baldwin 	print_syscall(trussinfo);
21100cf21b4fSBrian Somers 	fflush(trussinfo->outfile);
2111b9befd33SJohn Baldwin 
2112b9befd33SJohn Baldwin 	if (retval == NULL) {
2113b9befd33SJohn Baldwin 		/*
2114b9befd33SJohn Baldwin 		 * This system call resulted in the current thread's exit,
2115b9befd33SJohn Baldwin 		 * so there is no return value or error to display.
2116b9befd33SJohn Baldwin 		 */
2117b9befd33SJohn Baldwin 		fprintf(trussinfo->outfile, "\n");
2118b9befd33SJohn Baldwin 		return;
2119b9befd33SJohn Baldwin 	}
2120b9befd33SJohn Baldwin 
2121287b96ddSJohn Baldwin 	if (errorp) {
2122287b96ddSJohn Baldwin 		error = sysdecode_abi_to_freebsd_errno(t->proc->abi->abi,
2123287b96ddSJohn Baldwin 		    retval[0]);
21242b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0],
2125287b96ddSJohn Baldwin 		    error == INT_MAX ? "Unknown error" : strerror(error));
2126287b96ddSJohn Baldwin 	}
21272b75c8adSJohn Baldwin #ifndef __LP64__
21286c61b0f3SBryan Drewery 	else if (sc->ret_type == 2) {
21292b75c8adSJohn Baldwin 		off_t off;
21302b75c8adSJohn Baldwin 
21312b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
21322b75c8adSJohn Baldwin 		off = (off_t)retval[1] << 32 | retval[0];
21332b75c8adSJohn Baldwin #else
21342b75c8adSJohn Baldwin 		off = (off_t)retval[0] << 32 | retval[1];
21352b75c8adSJohn Baldwin #endif
21362b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " = %jd (0x%jx)\n", (intmax_t)off,
21372b75c8adSJohn Baldwin 		    (intmax_t)off);
21386cb533feSSean Eric Fagan 	}
21392b75c8adSJohn Baldwin #endif
21402b75c8adSJohn Baldwin 	else
21412b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval[0],
21422b75c8adSJohn Baldwin 		    retval[0]);
2143bbeaf6c0SSean Eric Fagan }
2144ee3b0f6eSDiomidis Spinellis 
2145ee3b0f6eSDiomidis Spinellis void
2146ee3b0f6eSDiomidis Spinellis print_summary(struct trussinfo *trussinfo)
2147ee3b0f6eSDiomidis Spinellis {
2148ee3b0f6eSDiomidis Spinellis 	struct timespec total = {0, 0};
214994355cfdSAndrey Zonov 	struct syscall *sc;
2150ee3b0f6eSDiomidis Spinellis 	int ncall, nerror;
2151ee3b0f6eSDiomidis Spinellis 
2152ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
2153ee3b0f6eSDiomidis Spinellis 	    "syscall", "seconds", "calls", "errors");
2154ee3b0f6eSDiomidis Spinellis 	ncall = nerror = 0;
21556c61b0f3SBryan Drewery 	STAILQ_FOREACH(sc, &syscalls, entries)
2156ee3b0f6eSDiomidis Spinellis 		if (sc->ncalls) {
215755a8d2bbSJaakko Heinonen 			fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
215855a8d2bbSJaakko Heinonen 			    sc->name, (intmax_t)sc->time.tv_sec,
215955a8d2bbSJaakko Heinonen 			    sc->time.tv_nsec, sc->ncalls, sc->nerror);
2160d9dcc463SXin LI 			timespecadd(&total, &sc->time, &total);
2161ee3b0f6eSDiomidis Spinellis 			ncall += sc->ncalls;
2162ee3b0f6eSDiomidis Spinellis 			nerror += sc->nerror;
2163ee3b0f6eSDiomidis Spinellis 		}
2164ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n",
2165ee3b0f6eSDiomidis Spinellis 	    "", "-------------", "-------", "-------");
216655a8d2bbSJaakko Heinonen 	fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
216755a8d2bbSJaakko Heinonen 	    "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror);
2168ee3b0f6eSDiomidis Spinellis }
2169