xref: /freebsd/usr.bin/truss/syscalls.c (revision bed418c8bd95178e376251453a136b6dfcbe23e9)
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,
89f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 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 } } },
95*bed418c8SJohn Baldwin 	{ .name = "cap_fcntls_get", .ret_type = 1, .nargs = 2,
96*bed418c8SJohn Baldwin 	  .args = { { Int, 0 }, { CapFcntlRights | OUT, 1 } } },
97*bed418c8SJohn Baldwin 	{ .name = "cap_fcntls_limit", .ret_type = 1, .nargs = 2,
98*bed418c8SJohn 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,
102f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Hex, 1 } } },
103f44fc79dSJohn Baldwin 	{ .name = "chmod", .ret_type = 1, .nargs = 2,
104ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Octal, 1 } } },
105f44fc79dSJohn Baldwin 	{ .name = "chown", .ret_type = 1, .nargs = 3,
106f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
107f44fc79dSJohn Baldwin 	{ .name = "chroot", .ret_type = 1, .nargs = 1,
108f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
109f44fc79dSJohn Baldwin 	{ .name = "clock_gettime", .ret_type = 1, .nargs = 2,
110f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timespec | OUT, 1 } } },
111ee3b0f6eSDiomidis Spinellis 	{ .name = "close", .ret_type = 1, .nargs = 1,
112ee3b0f6eSDiomidis Spinellis 	  .args = { { Int, 0 } } },
113f44fc79dSJohn Baldwin 	{ .name = "connect", .ret_type = 1, .nargs = 3,
114f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } },
115f44fc79dSJohn Baldwin 	{ .name = "connectat", .ret_type = 1, .nargs = 4,
116f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 },
117f44fc79dSJohn Baldwin 		    { Int, 3 } } },
118f44fc79dSJohn Baldwin 	{ .name = "eaccess", .ret_type = 1, .nargs = 2,
119f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Accessmode, 1 } } },
120f44fc79dSJohn Baldwin 	{ .name = "execve", .ret_type = 1, .nargs = 3,
121f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
122f44fc79dSJohn Baldwin 		    { ExecEnv | IN, 2 } } },
123f44fc79dSJohn Baldwin 	{ .name = "exit", .ret_type = 0, .nargs = 1,
124f44fc79dSJohn Baldwin 	  .args = { { Hex, 0 } } },
125f44fc79dSJohn Baldwin 	{ .name = "faccessat", .ret_type = 1, .nargs = 4,
126f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 },
127f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
128f44fc79dSJohn Baldwin 	{ .name = "fchmod", .ret_type = 1, .nargs = 2,
129f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Octal, 1 } } },
130f44fc79dSJohn Baldwin 	{ .name = "fchmodat", .ret_type = 1, .nargs = 4,
131f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Atflags, 3 } } },
132f44fc79dSJohn Baldwin 	{ .name = "fchown", .ret_type = 1, .nargs = 3,
133f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } },
134f44fc79dSJohn Baldwin 	{ .name = "fchownat", .ret_type = 1, .nargs = 5,
135f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 },
136f44fc79dSJohn Baldwin 		    { Atflags, 4 } } },
137f44fc79dSJohn Baldwin 	{ .name = "fcntl", .ret_type = 1, .nargs = 3,
138f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } },
139f44fc79dSJohn Baldwin 	{ .name = "fstat", .ret_type = 1, .nargs = 2,
140f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Stat | OUT, 1 } } },
141f44fc79dSJohn Baldwin 	{ .name = "fstatat", .ret_type = 1, .nargs = 4,
142f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat | OUT, 2 },
143f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
144f44fc79dSJohn Baldwin 	{ .name = "fstatfs", .ret_type = 1, .nargs = 2,
145f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { StatFs | OUT, 1 } } },
146f44fc79dSJohn Baldwin 	{ .name = "ftruncate", .ret_type = 1, .nargs = 2,
147c05cc0d6SJohn Baldwin 	  .args = { { Int | IN, 0 }, { QuadHex | IN, 1 } } },
148f44fc79dSJohn Baldwin 	{ .name = "futimens", .ret_type = 1, .nargs = 2,
149f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timespec2 | IN, 1 } } },
150f44fc79dSJohn Baldwin 	{ .name = "futimes", .ret_type = 1, .nargs = 2,
151f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timeval2 | IN, 1 } } },
152f44fc79dSJohn Baldwin 	{ .name = "futimesat", .ret_type = 1, .nargs = 3,
153f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timeval2 | IN, 2 } } },
154f44fc79dSJohn Baldwin 	{ .name = "getitimer", .ret_type = 1, .nargs = 2,
155f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Itimerval | OUT, 2 } } },
156f44fc79dSJohn Baldwin 	{ .name = "getpeername", .ret_type = 1, .nargs = 3,
157f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
158f44fc79dSJohn Baldwin 	{ .name = "getpgid", .ret_type = 1, .nargs = 1,
159f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
160f44fc79dSJohn Baldwin 	{ .name = "getrlimit", .ret_type = 1, .nargs = 2,
161f44fc79dSJohn Baldwin 	  .args = { { Resource, 0 }, { Rlimit | OUT, 1 } } },
162f44fc79dSJohn Baldwin 	{ .name = "getrusage", .ret_type = 1, .nargs = 2,
163f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Rusage | OUT, 1 } } },
164f44fc79dSJohn Baldwin 	{ .name = "getsid", .ret_type = 1, .nargs = 1,
165f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
166f44fc79dSJohn Baldwin 	{ .name = "getsockname", .ret_type = 1, .nargs = 3,
167f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
168f44fc79dSJohn Baldwin 	{ .name = "gettimeofday", .ret_type = 1, .nargs = 2,
169f44fc79dSJohn Baldwin 	  .args = { { Timeval | OUT, 0 }, { Ptr, 1 } } },
170f44fc79dSJohn Baldwin 	{ .name = "ioctl", .ret_type = 1, .nargs = 3,
171f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ioctl, 1 }, { Hex, 2 } } },
172f44fc79dSJohn Baldwin 	{ .name = "kevent", .ret_type = 1, .nargs = 6,
173f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 },
174f44fc79dSJohn Baldwin 		    { Int, 4 }, { Timespec, 5 } } },
175f44fc79dSJohn Baldwin 	{ .name = "kill", .ret_type = 1, .nargs = 2,
176f44fc79dSJohn Baldwin 	  .args = { { Int | IN, 0 }, { Signal | IN, 1 } } },
177f44fc79dSJohn Baldwin 	{ .name = "kldfind", .ret_type = 1, .nargs = 1,
178f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
179f44fc79dSJohn Baldwin 	{ .name = "kldfirstmod", .ret_type = 1, .nargs = 1,
180f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
181f44fc79dSJohn Baldwin 	{ .name = "kldload", .ret_type = 1, .nargs = 1,
182f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
183f44fc79dSJohn Baldwin 	{ .name = "kldnext", .ret_type = 1, .nargs = 1,
184f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
185f44fc79dSJohn Baldwin 	{ .name = "kldstat", .ret_type = 1, .nargs = 2,
186f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr, 1 } } },
187f44fc79dSJohn Baldwin 	{ .name = "kldunload", .ret_type = 1, .nargs = 1,
188f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
189f44fc79dSJohn Baldwin 	{ .name = "kse_release", .ret_type = 0, .nargs = 1,
190f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
191f44fc79dSJohn Baldwin 	{ .name = "lchflags", .ret_type = 1, .nargs = 2,
192f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Hex, 1 } } },
193f44fc79dSJohn Baldwin 	{ .name = "lchmod", .ret_type = 1, .nargs = 2,
194f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
195f44fc79dSJohn Baldwin 	{ .name = "lchown", .ret_type = 1, .nargs = 3,
196f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
1972b75c8adSJohn Baldwin 	{ .name = "link", .ret_type = 1, .nargs = 2,
198ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
1992b75c8adSJohn Baldwin 	{ .name = "linkat", .ret_type = 1, .nargs = 5,
2007d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 },
2017d897327SJohn Baldwin 		    { Atflags, 4 } } },
202f44fc79dSJohn Baldwin 	{ .name = "lseek", .ret_type = 2, .nargs = 3,
203c05cc0d6SJohn Baldwin 	  .args = { { Int, 0 }, { QuadHex, 1 }, { Whence, 2 } } },
204f44fc79dSJohn Baldwin 	{ .name = "lstat", .ret_type = 1, .nargs = 2,
205f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
206f44fc79dSJohn Baldwin 	{ .name = "lutimes", .ret_type = 1, .nargs = 2,
207f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
208f44fc79dSJohn Baldwin 	{ .name = "mkdir", .ret_type = 1, .nargs = 2,
209f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
210f44fc79dSJohn Baldwin 	{ .name = "mkdirat", .ret_type = 1, .nargs = 3,
211f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
2122b75c8adSJohn Baldwin 	{ .name = "mkfifo", .ret_type = 1, .nargs = 2,
213e82ce59cSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
2142b75c8adSJohn Baldwin 	{ .name = "mkfifoat", .ret_type = 1, .nargs = 3,
2157d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
2162b75c8adSJohn Baldwin 	{ .name = "mknod", .ret_type = 1, .nargs = 3,
217e82ce59cSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } },
2182b75c8adSJohn Baldwin 	{ .name = "mknodat", .ret_type = 1, .nargs = 4,
2197d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } },
220f44fc79dSJohn Baldwin 	{ .name = "mmap", .ret_type = 1, .nargs = 6,
221f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 },
222c05cc0d6SJohn Baldwin 		    { Int, 4 }, { QuadHex, 5 } } },
223f44fc79dSJohn Baldwin 	{ .name = "modfind", .ret_type = 1, .nargs = 1,
224f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
2252b75c8adSJohn Baldwin 	{ .name = "mount", .ret_type = 1, .nargs = 4,
226ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } },
227f44fc79dSJohn Baldwin 	{ .name = "mprotect", .ret_type = 1, .nargs = 3,
228f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } },
229f44fc79dSJohn Baldwin 	{ .name = "munmap", .ret_type = 1, .nargs = 2,
230f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 }, { Int, 1 } } },
231f44fc79dSJohn Baldwin 	{ .name = "nanosleep", .ret_type = 1, .nargs = 1,
232f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
233f44fc79dSJohn Baldwin 	{ .name = "open", .ret_type = 1, .nargs = 3,
234f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } },
235f44fc79dSJohn Baldwin 	{ .name = "openat", .ret_type = 1, .nargs = 4,
236f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Open, 2 },
237f44fc79dSJohn Baldwin 		    { Octal, 3 } } },
238f44fc79dSJohn Baldwin 	{ .name = "pathconf", .ret_type = 1, .nargs = 2,
239f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Pathconf, 1 } } },
240f44fc79dSJohn Baldwin 	{ .name = "pipe", .ret_type = 1, .nargs = 1,
241f44fc79dSJohn Baldwin 	  .args = { { PipeFds | OUT, 0 } } },
242f44fc79dSJohn Baldwin 	{ .name = "pipe2", .ret_type = 1, .nargs = 2,
2439289f547SJohn Baldwin 	  .args = { { Ptr, 0 }, { Pipe2, 1 } } },
244f44fc79dSJohn Baldwin 	{ .name = "poll", .ret_type = 1, .nargs = 3,
245f44fc79dSJohn Baldwin 	  .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } },
246f44fc79dSJohn Baldwin 	{ .name = "posix_openpt", .ret_type = 1, .nargs = 1,
247f44fc79dSJohn Baldwin 	  .args = { { Open, 0 } } },
248f44fc79dSJohn Baldwin 	{ .name = "procctl", .ret_type = 1, .nargs = 4,
249c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { Procctl, 2 }, { Ptr, 3 } } },
250f44fc79dSJohn Baldwin 	{ .name = "read", .ret_type = 1, .nargs = 3,
251f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } },
252f44fc79dSJohn Baldwin 	{ .name = "readlink", .ret_type = 1, .nargs = 3,
253f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Int, 2 } } },
254f44fc79dSJohn Baldwin 	{ .name = "readlinkat", .ret_type = 1, .nargs = 4,
255f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 },
2567d897327SJohn Baldwin 		    { Int, 3 } } },
257ee3b0f6eSDiomidis Spinellis 	{ .name = "recvfrom", .ret_type = 1, .nargs = 6,
2580a46af44SJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 }, { Hex, 3 },
2590a46af44SJohn Baldwin 		    { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } },
260f44fc79dSJohn Baldwin 	{ .name = "rename", .ret_type = 1, .nargs = 2,
261f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Name, 1 } } },
262f44fc79dSJohn Baldwin 	{ .name = "renameat", .ret_type = 1, .nargs = 4,
263f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 } } },
264f44fc79dSJohn Baldwin 	{ .name = "rfork", .ret_type = 1, .nargs = 1,
265f44fc79dSJohn Baldwin 	  .args = { { Rforkflags, 0 } } },
266cca89ee3SBryan Drewery 	{ .name = "rmdir", .ret_type = 1, .nargs = 1,
267cca89ee3SBryan Drewery 	  .args = { { Name, 0 } } },
268ee3b0f6eSDiomidis Spinellis 	{ .name = "select", .ret_type = 1, .nargs = 5,
2690a46af44SJohn Baldwin 	  .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 },
2700a46af44SJohn Baldwin 		    { Timeval, 4 } } },
271f44fc79dSJohn Baldwin 	{ .name = "sendto", .ret_type = 1, .nargs = 6,
272f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 },
273f44fc79dSJohn Baldwin 		    { Sockaddr | IN, 4 }, { Ptr | IN, 5 } } },
274ee3b0f6eSDiomidis Spinellis 	{ .name = "setitimer", .ret_type = 1, .nargs = 3,
275ee3b0f6eSDiomidis Spinellis 	  .args = { { Int, 0 }, { Itimerval, 1 }, { Itimerval | OUT, 2 } } },
276f44fc79dSJohn Baldwin 	{ .name = "setrlimit", .ret_type = 1, .nargs = 2,
277f44fc79dSJohn Baldwin 	  .args = { { Resource, 0 }, { Rlimit | IN, 1 } } },
278f44fc79dSJohn Baldwin 	{ .name = "shutdown", .ret_type = 1, .nargs = 2,
279f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Shutdown, 1 } } },
280f44fc79dSJohn Baldwin 	{ .name = "sigaction", .ret_type = 1, .nargs = 3,
281f44fc79dSJohn Baldwin 	  .args = { { Signal, 0 }, { Sigaction | IN, 1 },
282f44fc79dSJohn Baldwin 		    { Sigaction | OUT, 2 } } },
2832b75c8adSJohn Baldwin 	{ .name = "sigpending", .ret_type = 1, .nargs = 1,
284b289a8d7SJohn Baldwin 	  .args = { { Sigset | OUT, 0 } } },
2852b75c8adSJohn Baldwin 	{ .name = "sigprocmask", .ret_type = 1, .nargs = 3,
286ee3b0f6eSDiomidis Spinellis 	  .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } },
2872b75c8adSJohn Baldwin 	{ .name = "sigqueue", .ret_type = 1, .nargs = 3,
288b289a8d7SJohn Baldwin 	  .args = { { Int, 0 }, { Signal, 1 }, { LongHex, 2 } } },
2892b75c8adSJohn Baldwin 	{ .name = "sigreturn", .ret_type = 1, .nargs = 1,
290b289a8d7SJohn Baldwin 	  .args = { { Ptr, 0 } } },
2912b75c8adSJohn Baldwin 	{ .name = "sigsuspend", .ret_type = 1, .nargs = 1,
292b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 } } },
293b289a8d7SJohn Baldwin 	{ .name = "sigtimedwait", .ret_type = 1, .nargs = 3,
294b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 }, { Timespec | IN, 2 } } },
295b289a8d7SJohn Baldwin 	{ .name = "sigwait", .ret_type = 1, .nargs = 2,
296b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 } } },
297b289a8d7SJohn Baldwin 	{ .name = "sigwaitinfo", .ret_type = 1, .nargs = 2,
298b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Ptr, 1 } } },
299ee3b0f6eSDiomidis Spinellis 	{ .name = "socket", .ret_type = 1, .nargs = 3,
300ee3b0f6eSDiomidis Spinellis 	  .args = { { Sockdomain, 0 }, { Socktype, 1 }, { Int, 2 } } },
301f44fc79dSJohn Baldwin 	{ .name = "stat", .ret_type = 1, .nargs = 2,
302f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
303f44fc79dSJohn Baldwin 	{ .name = "statfs", .ret_type = 1, .nargs = 2,
304f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { StatFs | OUT, 1 } } },
305ee3b0f6eSDiomidis Spinellis 	{ .name = "symlink", .ret_type = 1, .nargs = 2,
306ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
3077d897327SJohn Baldwin 	{ .name = "symlinkat", .ret_type = 1, .nargs = 3,
3087d897327SJohn Baldwin 	  .args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } },
309f44fc79dSJohn Baldwin 	{ .name = "sysarch", .ret_type = 1, .nargs = 2,
310f44fc79dSJohn Baldwin 	  .args = { { Sysarch, 0 }, { Ptr, 1 } } },
311f44fc79dSJohn Baldwin 	{ .name = "thr_kill", .ret_type = 1, .nargs = 2,
312f44fc79dSJohn Baldwin 	  .args = { { Long, 0 }, { Signal, 1 } } },
313f44fc79dSJohn Baldwin 	{ .name = "thr_self", .ret_type = 1, .nargs = 1,
314f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 } } },
315f44fc79dSJohn Baldwin 	{ .name = "truncate", .ret_type = 1, .nargs = 2,
316c05cc0d6SJohn Baldwin 	  .args = { { Name | IN, 0 }, { QuadHex | IN, 1 } } },
317f44fc79dSJohn Baldwin #if 0
318f44fc79dSJohn Baldwin 	/* Does not exist */
319f44fc79dSJohn Baldwin 	{ .name = "umount", .ret_type = 1, .nargs = 2,
320f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 2 } } },
321f44fc79dSJohn Baldwin #endif
322f44fc79dSJohn Baldwin 	{ .name = "unlink", .ret_type = 1, .nargs = 1,
323f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
324f44fc79dSJohn Baldwin 	{ .name = "unlinkat", .ret_type = 1, .nargs = 3,
325f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } },
326f44fc79dSJohn Baldwin 	{ .name = "unmount", .ret_type = 1, .nargs = 2,
327f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 } } },
328f44fc79dSJohn Baldwin 	{ .name = "utimensat", .ret_type = 1, .nargs = 4,
329f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 },
330f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
331f44fc79dSJohn Baldwin 	{ .name = "utimes", .ret_type = 1, .nargs = 2,
332f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
333195aef99SBryan Drewery 	{ .name = "utrace", .ret_type = 1, .nargs = 1,
334195aef99SBryan Drewery 	  .args = { { Utrace, 0 } } },
33534763d1cSJohn Baldwin 	{ .name = "wait4", .ret_type = 1, .nargs = 4,
33634763d1cSJohn Baldwin 	  .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 },
33734763d1cSJohn Baldwin 		    { Rusage | OUT, 3 } } },
33834763d1cSJohn Baldwin 	{ .name = "wait6", .ret_type = 1, .nargs = 6,
339c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { ExitStatus | OUT, 2 },
340c05cc0d6SJohn Baldwin 		    { Waitoptions, 3 }, { Rusage | OUT, 4 }, { Ptr, 5 } } },
341f44fc79dSJohn Baldwin 	{ .name = "write", .ret_type = 1, .nargs = 3,
342f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 } } },
343f44fc79dSJohn Baldwin 
344f44fc79dSJohn Baldwin 	/* Linux ABI */
345f44fc79dSJohn Baldwin 	{ .name = "linux_access", .ret_type = 1, .nargs = 2,
346f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Accessmode, 1 } } },
347f44fc79dSJohn Baldwin 	{ .name = "linux_execve", .ret_type = 1, .nargs = 3,
348f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
349f44fc79dSJohn Baldwin 		    { ExecEnv | IN, 2 } } },
350f44fc79dSJohn Baldwin 	{ .name = "linux_lseek", .ret_type = 2, .nargs = 3,
351f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } },
352f44fc79dSJohn Baldwin 	{ .name = "linux_mkdir", .ret_type = 1, .nargs = 2,
353f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Int, 1 } } },
354f44fc79dSJohn Baldwin 	{ .name = "linux_newfstat", .ret_type = 1, .nargs = 2,
355f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr | OUT, 1 } } },
356f44fc79dSJohn Baldwin 	{ .name = "linux_newstat", .ret_type = 1, .nargs = 2,
357f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
358f44fc79dSJohn Baldwin 	{ .name = "linux_open", .ret_type = 1, .nargs = 3,
359f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } },
360f44fc79dSJohn Baldwin 	{ .name = "linux_readlink", .ret_type = 1, .nargs = 3,
361f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Name | OUT, 1 }, { Int, 2 } } },
362f44fc79dSJohn Baldwin 	{ .name = "linux_socketcall", .ret_type = 1, .nargs = 2,
363f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { LinuxSockArgs, 1 } } },
36464f4703bSJohn Baldwin 	{ .name = "linux_stat64", .ret_type = 1, .nargs = 2,
36564f4703bSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
366f44fc79dSJohn Baldwin 
367808d9805SEd Schouten 	/* CloudABI system calls. */
368808d9805SEd Schouten 	{ .name = "cloudabi_sys_clock_res_get", .ret_type = 1, .nargs = 1,
369808d9805SEd Schouten 	  .args = { { CloudABIClockID, 0 } } },
370808d9805SEd Schouten 	{ .name = "cloudabi_sys_clock_time_get", .ret_type = 1, .nargs = 2,
371808d9805SEd Schouten 	  .args = { { CloudABIClockID, 0 }, { CloudABITimestamp, 1 } } },
372808d9805SEd Schouten 	{ .name = "cloudabi_sys_condvar_signal", .ret_type = 1, .nargs = 3,
373808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 }, { UInt, 2 } } },
374808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_close", .ret_type = 1, .nargs = 1,
375808d9805SEd Schouten 	  .args = { { Int, 0 } } },
376808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_create1", .ret_type = 1, .nargs = 1,
377808d9805SEd Schouten 	  .args = { { CloudABIFileType, 0 } } },
378808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_create2", .ret_type = 1, .nargs = 2,
379808d9805SEd Schouten 	  .args = { { CloudABIFileType, 0 }, { PipeFds | OUT, 0 } } },
380808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_datasync", .ret_type = 1, .nargs = 1,
381808d9805SEd Schouten 	  .args = { { Int, 0 } } },
382808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_dup", .ret_type = 1, .nargs = 1,
383808d9805SEd Schouten 	  .args = { { Int, 0 } } },
384808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_replace", .ret_type = 1, .nargs = 2,
385808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 } } },
386808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_seek", .ret_type = 1, .nargs = 3,
387808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { CloudABIWhence, 2 } } },
388808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_stat_get", .ret_type = 1, .nargs = 2,
389808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFDStat | OUT, 1 } } },
390808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_stat_put", .ret_type = 1, .nargs = 3,
391808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFDStat | IN, 1 },
392808d9805SEd Schouten 	            { ClouduABIFDSFlags, 2 } } },
393808d9805SEd Schouten 	{ .name = "cloudabi_sys_fd_sync", .ret_type = 1, .nargs = 1,
394808d9805SEd Schouten 	  .args = { { Int, 0 } } },
395808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_advise", .ret_type = 1, .nargs = 4,
396808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 },
397808d9805SEd Schouten 	            { CloudABIAdvice, 3 } } },
398808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_allocate", .ret_type = 1, .nargs = 3,
399808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } },
400808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_create", .ret_type = 1, .nargs = 3,
401808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
402808d9805SEd Schouten 	            { CloudABIFileType, 3 } } },
403808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_link", .ret_type = 1, .nargs = 4,
404808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
405808d9805SEd Schouten 	            { Int, 3 }, { BinString | IN, 4 } } },
406808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_open", .ret_type = 1, .nargs = 4,
407808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
408808d9805SEd Schouten 	            { CloudABIOFlags, 3 }, { CloudABIFDStat | IN, 4 } } },
409808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_readdir", .ret_type = 1, .nargs = 4,
410808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 },
411808d9805SEd Schouten 	            { Int, 3 } } },
412808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_readlink", .ret_type = 1, .nargs = 4,
413808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
414808d9805SEd Schouten 	            { BinString | OUT, 3 }, { Int, 4 } } },
415808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_rename", .ret_type = 1, .nargs = 4,
416808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
417808d9805SEd Schouten 	            { Int, 3 }, { BinString | IN, 4 } } },
418808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_fget", .ret_type = 1, .nargs = 2,
419808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFileStat | OUT, 1 } } },
420808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_fput", .ret_type = 1, .nargs = 3,
421808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABIFileStat | IN, 1 },
422808d9805SEd Schouten 	            { CloudABIFSFlags, 2 } } },
423808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_get", .ret_type = 1, .nargs = 3,
424808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
425808d9805SEd Schouten 	            { CloudABIFileStat | OUT, 3 } } },
426808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_stat_put", .ret_type = 1, .nargs = 4,
427808d9805SEd Schouten 	  .args = { { CloudABILookup, 0 }, { BinString | IN, 1 },
428808d9805SEd Schouten 	            { CloudABIFileStat | IN, 3 }, { CloudABIFSFlags, 4 } } },
429808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_symlink", .ret_type = 1, .nargs = 3,
430808d9805SEd Schouten 	  .args = { { BinString | IN, 0 },
431808d9805SEd Schouten 	            { Int, 2 }, { BinString | IN, 3 } } },
432808d9805SEd Schouten 	{ .name = "cloudabi_sys_file_unlink", .ret_type = 1, .nargs = 3,
433808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 },
434808d9805SEd Schouten 	            { CloudABIULFlags, 3 } } },
435808d9805SEd Schouten 	{ .name = "cloudabi_sys_lock_unlock", .ret_type = 1, .nargs = 2,
436808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } },
437808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_advise", .ret_type = 1, .nargs = 3,
438808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIAdvice, 2 } } },
439808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_lock", .ret_type = 1, .nargs = 2,
440808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
441808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_map", .ret_type = 1, .nargs = 6,
442808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 },
443808d9805SEd Schouten 	            { CloudABIMFlags, 3 }, { Int, 4 }, { Int, 5 } } },
444808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_protect", .ret_type = 1, .nargs = 3,
445808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 } } },
446808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_sync", .ret_type = 1, .nargs = 3,
447808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMSFlags, 2 } } },
448808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_unlock", .ret_type = 1, .nargs = 2,
449808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
450808d9805SEd Schouten 	{ .name = "cloudabi_sys_mem_unmap", .ret_type = 1, .nargs = 2,
451808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { Int, 1 } } },
452808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_exec", .ret_type = 1, .nargs = 5,
453808d9805SEd Schouten 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 },
454808d9805SEd Schouten 	            { IntArray, 3 }, { Int, 4 } } },
455808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_exit", .ret_type = 1, .nargs = 1,
456808d9805SEd Schouten 	  .args = { { Int, 0 } } },
457808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_fork", .ret_type = 1, .nargs = 0 },
458808d9805SEd Schouten 	{ .name = "cloudabi_sys_proc_raise", .ret_type = 1, .nargs = 1,
459808d9805SEd Schouten 	  .args = { { CloudABISignal, 0 } } },
460808d9805SEd Schouten 	{ .name = "cloudabi_sys_random_get", .ret_type = 1, .nargs = 2,
461808d9805SEd Schouten 	  .args = { { BinString | OUT, 0 }, { Int, 1 } } },
462808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_accept", .ret_type = 1, .nargs = 2,
463808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 } } },
464808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_bind", .ret_type = 1, .nargs = 3,
465808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } },
466808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_connect", .ret_type = 1, .nargs = 3,
467808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } },
468808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_listen", .ret_type = 1, .nargs = 2,
469808d9805SEd Schouten 	  .args = { { Int, 0 }, { Int, 1 } } },
470808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_shutdown", .ret_type = 1, .nargs = 2,
471808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISDFlags, 1 } } },
472808d9805SEd Schouten 	{ .name = "cloudabi_sys_sock_stat_get", .ret_type = 1, .nargs = 3,
473808d9805SEd Schouten 	  .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 },
474808d9805SEd Schouten 	            { CloudABISSFlags, 2 } } },
475808d9805SEd Schouten 	{ .name = "cloudabi_sys_thread_exit", .ret_type = 1, .nargs = 2,
476808d9805SEd Schouten 	  .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } },
477808d9805SEd Schouten 	{ .name = "cloudabi_sys_thread_yield", .ret_type = 1, .nargs = 0 },
478808d9805SEd Schouten 
479ee3b0f6eSDiomidis Spinellis 	{ .name = 0 },
480bbeaf6c0SSean Eric Fagan };
4816c61b0f3SBryan Drewery static STAILQ_HEAD(, syscall) syscalls;
482bbeaf6c0SSean Eric Fagan 
483081e5c48SPav Lucistnik /* Xlat idea taken from strace */
484081e5c48SPav Lucistnik struct xlat {
485081e5c48SPav Lucistnik 	int val;
4865d2d083cSXin LI 	const char *str;
487081e5c48SPav Lucistnik };
488081e5c48SPav Lucistnik 
489081e5c48SPav Lucistnik #define	X(a)	{ a, #a },
490081e5c48SPav Lucistnik #define	XEND	{ 0, NULL }
491081e5c48SPav Lucistnik 
492081e5c48SPav Lucistnik static struct xlat kevent_filters[] = {
493081e5c48SPav Lucistnik 	X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE)
494081e5c48SPav Lucistnik 	X(EVFILT_PROC) X(EVFILT_SIGNAL) X(EVFILT_TIMER)
495d98d7ba0SJohn Baldwin 	X(EVFILT_PROCDESC) X(EVFILT_FS) X(EVFILT_LIO) X(EVFILT_USER)
496d98d7ba0SJohn Baldwin 	X(EVFILT_SENDFILE) XEND
497081e5c48SPav Lucistnik };
498081e5c48SPav Lucistnik 
499081e5c48SPav Lucistnik static struct xlat kevent_flags[] = {
500081e5c48SPav Lucistnik 	X(EV_ADD) X(EV_DELETE) X(EV_ENABLE) X(EV_DISABLE) X(EV_ONESHOT)
501d98d7ba0SJohn Baldwin 	X(EV_CLEAR) X(EV_RECEIPT) X(EV_DISPATCH) X(EV_FORCEONESHOT)
502d98d7ba0SJohn Baldwin 	X(EV_DROP) X(EV_FLAG1) X(EV_ERROR) X(EV_EOF) XEND
503081e5c48SPav Lucistnik };
504081e5c48SPav Lucistnik 
505c915ff03SJohn Baldwin static struct xlat kevent_user_ffctrl[] = {
506c915ff03SJohn Baldwin 	X(NOTE_FFNOP) X(NOTE_FFAND) X(NOTE_FFOR) X(NOTE_FFCOPY)
507c915ff03SJohn Baldwin 	XEND
508c915ff03SJohn Baldwin };
509c915ff03SJohn Baldwin 
510c915ff03SJohn Baldwin static struct xlat kevent_rdwr_fflags[] = {
511c915ff03SJohn Baldwin 	X(NOTE_LOWAT) X(NOTE_FILE_POLL) XEND
512c915ff03SJohn Baldwin };
513c915ff03SJohn Baldwin 
514c915ff03SJohn Baldwin static struct xlat kevent_vnode_fflags[] = {
515c915ff03SJohn Baldwin 	X(NOTE_DELETE) X(NOTE_WRITE) X(NOTE_EXTEND) X(NOTE_ATTRIB)
516c915ff03SJohn Baldwin 	X(NOTE_LINK) X(NOTE_RENAME) X(NOTE_REVOKE) XEND
517c915ff03SJohn Baldwin };
518c915ff03SJohn Baldwin 
519c915ff03SJohn Baldwin static struct xlat kevent_proc_fflags[] = {
520c915ff03SJohn Baldwin 	X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_TRACK) X(NOTE_TRACKERR)
521c915ff03SJohn Baldwin 	X(NOTE_CHILD) XEND
522c915ff03SJohn Baldwin };
523c915ff03SJohn Baldwin 
524c915ff03SJohn Baldwin static struct xlat kevent_timer_fflags[] = {
525c915ff03SJohn Baldwin 	X(NOTE_SECONDS) X(NOTE_MSECONDS) X(NOTE_USECONDS) X(NOTE_NSECONDS)
526c915ff03SJohn Baldwin 	XEND
527c915ff03SJohn Baldwin };
528c915ff03SJohn Baldwin 
529a02c83afSEd Schouten static struct xlat poll_flags[] = {
530081e5c48SPav Lucistnik 	X(POLLSTANDARD) X(POLLIN) X(POLLPRI) X(POLLOUT) X(POLLERR)
531081e5c48SPav Lucistnik 	X(POLLHUP) X(POLLNVAL) X(POLLRDNORM) X(POLLRDBAND)
532081e5c48SPav Lucistnik 	X(POLLWRBAND) X(POLLINIGNEOF) XEND
533081e5c48SPav Lucistnik };
534081e5c48SPav Lucistnik 
535081e5c48SPav Lucistnik static struct xlat sigaction_flags[] = {
536081e5c48SPav Lucistnik 	X(SA_ONSTACK) X(SA_RESTART) X(SA_RESETHAND) X(SA_NOCLDSTOP)
537081e5c48SPav Lucistnik 	X(SA_NODEFER) X(SA_NOCLDWAIT) X(SA_SIGINFO) XEND
538081e5c48SPav Lucistnik };
539081e5c48SPav Lucistnik 
540081e5c48SPav Lucistnik static struct xlat pathconf_arg[] = {
541081e5c48SPav Lucistnik 	X(_PC_LINK_MAX)  X(_PC_MAX_CANON)  X(_PC_MAX_INPUT)
542081e5c48SPav Lucistnik 	X(_PC_NAME_MAX) X(_PC_PATH_MAX) X(_PC_PIPE_BUF)
543081e5c48SPav Lucistnik 	X(_PC_CHOWN_RESTRICTED) X(_PC_NO_TRUNC) X(_PC_VDISABLE)
544081e5c48SPav Lucistnik 	X(_PC_ASYNC_IO) X(_PC_PRIO_IO) X(_PC_SYNC_IO)
545081e5c48SPav Lucistnik 	X(_PC_ALLOC_SIZE_MIN) X(_PC_FILESIZEBITS)
546081e5c48SPav Lucistnik 	X(_PC_REC_INCR_XFER_SIZE) X(_PC_REC_MAX_XFER_SIZE)
547081e5c48SPav Lucistnik 	X(_PC_REC_MIN_XFER_SIZE) X(_PC_REC_XFER_ALIGN)
548081e5c48SPav Lucistnik 	X(_PC_SYMLINK_MAX) X(_PC_ACL_EXTENDED) X(_PC_ACL_PATH_MAX)
549081e5c48SPav Lucistnik 	X(_PC_CAP_PRESENT) X(_PC_INF_PRESENT) X(_PC_MAC_PRESENT)
550d98d7ba0SJohn Baldwin 	X(_PC_ACL_NFS4) X(_PC_MIN_HOLE_SIZE) XEND
551081e5c48SPav Lucistnik };
552081e5c48SPav Lucistnik 
5537d897327SJohn Baldwin static struct xlat at_flags[] = {
5547d897327SJohn Baldwin 	X(AT_EACCESS) X(AT_SYMLINK_NOFOLLOW) X(AT_SYMLINK_FOLLOW)
5557d897327SJohn Baldwin 	X(AT_REMOVEDIR) XEND
5567d897327SJohn Baldwin };
5577d897327SJohn Baldwin 
558b289a8d7SJohn Baldwin static struct xlat sysarch_ops[] = {
559b289a8d7SJohn Baldwin #if defined(__i386__) || defined(__amd64__)
560b289a8d7SJohn Baldwin 	X(I386_GET_LDT) X(I386_SET_LDT) X(I386_GET_IOPERM) X(I386_SET_IOPERM)
561b289a8d7SJohn Baldwin 	X(I386_VM86) X(I386_GET_FSBASE) X(I386_SET_FSBASE) X(I386_GET_GSBASE)
562b289a8d7SJohn Baldwin 	X(I386_SET_GSBASE) X(I386_GET_XFPUSTATE) X(AMD64_GET_FSBASE)
563b289a8d7SJohn Baldwin 	X(AMD64_SET_FSBASE) X(AMD64_GET_GSBASE) X(AMD64_SET_GSBASE)
564b289a8d7SJohn Baldwin 	X(AMD64_GET_XFPUSTATE)
565b289a8d7SJohn Baldwin #endif
566b289a8d7SJohn Baldwin 	XEND
567b289a8d7SJohn Baldwin };
568fb7eabb0SJohn Baldwin 
569fb7eabb0SJohn Baldwin static struct xlat linux_socketcall_ops[] = {
570fb7eabb0SJohn Baldwin 	X(LINUX_SOCKET) X(LINUX_BIND) X(LINUX_CONNECT) X(LINUX_LISTEN)
571fb7eabb0SJohn Baldwin 	X(LINUX_ACCEPT) X(LINUX_GETSOCKNAME) X(LINUX_GETPEERNAME)
572fb7eabb0SJohn Baldwin 	X(LINUX_SOCKETPAIR) X(LINUX_SEND) X(LINUX_RECV) X(LINUX_SENDTO)
573fb7eabb0SJohn Baldwin 	X(LINUX_RECVFROM) X(LINUX_SHUTDOWN) X(LINUX_SETSOCKOPT)
574fb7eabb0SJohn Baldwin 	X(LINUX_GETSOCKOPT) X(LINUX_SENDMSG) X(LINUX_RECVMSG)
575fb7eabb0SJohn Baldwin 	XEND
576fb7eabb0SJohn Baldwin };
577fb7eabb0SJohn Baldwin 
578081e5c48SPav Lucistnik #undef X
579808d9805SEd Schouten #define	X(a)	{ CLOUDABI_##a, #a },
580808d9805SEd Schouten 
581808d9805SEd Schouten static struct xlat cloudabi_advice[] = {
582808d9805SEd Schouten 	X(ADVICE_DONTNEED) X(ADVICE_NOREUSE) X(ADVICE_NORMAL)
583808d9805SEd Schouten 	X(ADVICE_RANDOM) X(ADVICE_SEQUENTIAL) X(ADVICE_WILLNEED)
584808d9805SEd Schouten 	XEND
585808d9805SEd Schouten };
586808d9805SEd Schouten 
587808d9805SEd Schouten static struct xlat cloudabi_clockid[] = {
588808d9805SEd Schouten 	X(CLOCK_MONOTONIC) X(CLOCK_PROCESS_CPUTIME_ID)
589808d9805SEd Schouten 	X(CLOCK_REALTIME) X(CLOCK_THREAD_CPUTIME_ID)
590808d9805SEd Schouten 	XEND
591808d9805SEd Schouten };
592808d9805SEd Schouten 
593808d9805SEd Schouten static struct xlat cloudabi_errno[] = {
594808d9805SEd Schouten 	X(E2BIG) X(EACCES) X(EADDRINUSE) X(EADDRNOTAVAIL)
595808d9805SEd Schouten 	X(EAFNOSUPPORT) X(EAGAIN) X(EALREADY) X(EBADF) X(EBADMSG)
596808d9805SEd Schouten 	X(EBUSY) X(ECANCELED) X(ECHILD) X(ECONNABORTED) X(ECONNREFUSED)
597808d9805SEd Schouten 	X(ECONNRESET) X(EDEADLK) X(EDESTADDRREQ) X(EDOM) X(EDQUOT)
598808d9805SEd Schouten 	X(EEXIST) X(EFAULT) X(EFBIG) X(EHOSTUNREACH) X(EIDRM) X(EILSEQ)
599808d9805SEd Schouten 	X(EINPROGRESS) X(EINTR) X(EINVAL) X(EIO) X(EISCONN) X(EISDIR)
600808d9805SEd Schouten 	X(ELOOP) X(EMFILE) X(EMLINK) X(EMSGSIZE) X(EMULTIHOP)
601808d9805SEd Schouten 	X(ENAMETOOLONG) X(ENETDOWN) X(ENETRESET) X(ENETUNREACH)
602808d9805SEd Schouten 	X(ENFILE) X(ENOBUFS) X(ENODEV) X(ENOENT) X(ENOEXEC) X(ENOLCK)
603808d9805SEd Schouten 	X(ENOLINK) X(ENOMEM) X(ENOMSG) X(ENOPROTOOPT) X(ENOSPC)
604808d9805SEd Schouten 	X(ENOSYS) X(ENOTCONN) X(ENOTDIR) X(ENOTEMPTY) X(ENOTRECOVERABLE)
605808d9805SEd Schouten 	X(ENOTSOCK) X(ENOTSUP) X(ENOTTY) X(ENXIO) X(EOVERFLOW)
606808d9805SEd Schouten 	X(EOWNERDEAD) X(EPERM) X(EPIPE) X(EPROTO) X(EPROTONOSUPPORT)
607808d9805SEd Schouten 	X(EPROTOTYPE) X(ERANGE) X(EROFS) X(ESPIPE) X(ESRCH) X(ESTALE)
608808d9805SEd Schouten 	X(ETIMEDOUT) X(ETXTBSY) X(EXDEV) X(ENOTCAPABLE)
609808d9805SEd Schouten 	XEND
610808d9805SEd Schouten };
611808d9805SEd Schouten 
612808d9805SEd Schouten static struct xlat cloudabi_fdflags[] = {
613808d9805SEd Schouten 	X(FDFLAG_APPEND) X(FDFLAG_DSYNC) X(FDFLAG_NONBLOCK)
614808d9805SEd Schouten 	X(FDFLAG_RSYNC) X(FDFLAG_SYNC)
615808d9805SEd Schouten 	XEND
616808d9805SEd Schouten };
617808d9805SEd Schouten 
618808d9805SEd Schouten static struct xlat cloudabi_fdsflags[] = {
619808d9805SEd Schouten 	X(FDSTAT_FLAGS) X(FDSTAT_RIGHTS)
620808d9805SEd Schouten 	XEND
621808d9805SEd Schouten };
622808d9805SEd Schouten 
623808d9805SEd Schouten static struct xlat cloudabi_filetype[] = {
624808d9805SEd Schouten 	X(FILETYPE_UNKNOWN) X(FILETYPE_BLOCK_DEVICE)
625808d9805SEd Schouten 	X(FILETYPE_CHARACTER_DEVICE) X(FILETYPE_DIRECTORY)
626808d9805SEd Schouten 	X(FILETYPE_FIFO) X(FILETYPE_POLL) X(FILETYPE_PROCESS)
627808d9805SEd Schouten 	X(FILETYPE_REGULAR_FILE) X(FILETYPE_SHARED_MEMORY)
628808d9805SEd Schouten 	X(FILETYPE_SOCKET_DGRAM) X(FILETYPE_SOCKET_SEQPACKET)
629808d9805SEd Schouten 	X(FILETYPE_SOCKET_STREAM) X(FILETYPE_SYMBOLIC_LINK)
630808d9805SEd Schouten 	XEND
631808d9805SEd Schouten };
632808d9805SEd Schouten 
633808d9805SEd Schouten static struct xlat cloudabi_fsflags[] = {
634808d9805SEd Schouten 	X(FILESTAT_ATIM) X(FILESTAT_ATIM_NOW) X(FILESTAT_MTIM)
635808d9805SEd Schouten 	X(FILESTAT_MTIM_NOW) X(FILESTAT_SIZE)
636808d9805SEd Schouten 	XEND
637808d9805SEd Schouten };
638808d9805SEd Schouten 
639808d9805SEd Schouten static struct xlat cloudabi_mflags[] = {
640808d9805SEd Schouten 	X(MAP_ANON) X(MAP_FIXED) X(MAP_PRIVATE) X(MAP_SHARED)
641808d9805SEd Schouten 	XEND
642808d9805SEd Schouten };
643808d9805SEd Schouten 
644808d9805SEd Schouten static struct xlat cloudabi_mprot[] = {
645808d9805SEd Schouten 	X(PROT_EXEC) X(PROT_WRITE) X(PROT_READ)
646808d9805SEd Schouten 	XEND
647808d9805SEd Schouten };
648808d9805SEd Schouten 
649808d9805SEd Schouten static struct xlat cloudabi_msflags[] = {
650808d9805SEd Schouten 	X(MS_ASYNC) X(MS_INVALIDATE) X(MS_SYNC)
651808d9805SEd Schouten 	XEND
652808d9805SEd Schouten };
653808d9805SEd Schouten 
654808d9805SEd Schouten static struct xlat cloudabi_oflags[] = {
655808d9805SEd Schouten 	X(O_CREAT) X(O_DIRECTORY) X(O_EXCL) X(O_TRUNC)
656808d9805SEd Schouten 	XEND
657808d9805SEd Schouten };
658808d9805SEd Schouten 
659808d9805SEd Schouten static struct xlat cloudabi_sa_family[] = {
660808d9805SEd Schouten 	X(AF_UNSPEC) X(AF_INET) X(AF_INET6) X(AF_UNIX)
661808d9805SEd Schouten 	XEND
662808d9805SEd Schouten };
663808d9805SEd Schouten 
664808d9805SEd Schouten static struct xlat cloudabi_sdflags[] = {
665808d9805SEd Schouten 	X(SHUT_RD) X(SHUT_WR)
666808d9805SEd Schouten 	XEND
667808d9805SEd Schouten };
668808d9805SEd Schouten 
669808d9805SEd Schouten static struct xlat cloudabi_signal[] = {
670808d9805SEd Schouten 	X(SIGABRT) X(SIGALRM) X(SIGBUS) X(SIGCHLD) X(SIGCONT) X(SIGFPE)
671808d9805SEd Schouten 	X(SIGHUP) X(SIGILL) X(SIGINT) X(SIGKILL) X(SIGPIPE) X(SIGQUIT)
672808d9805SEd Schouten 	X(SIGSEGV) X(SIGSTOP) X(SIGSYS) X(SIGTERM) X(SIGTRAP) X(SIGTSTP)
673808d9805SEd Schouten 	X(SIGTTIN) X(SIGTTOU) X(SIGURG) X(SIGUSR1) X(SIGUSR2)
674808d9805SEd Schouten 	X(SIGVTALRM) X(SIGXCPU) X(SIGXFSZ)
675808d9805SEd Schouten 	XEND
676808d9805SEd Schouten };
677808d9805SEd Schouten 
678808d9805SEd Schouten static struct xlat cloudabi_ssflags[] = {
679808d9805SEd Schouten 	X(SOCKSTAT_CLEAR_ERROR)
680808d9805SEd Schouten 	XEND
681808d9805SEd Schouten };
682808d9805SEd Schouten 
683808d9805SEd Schouten static struct xlat cloudabi_ssstate[] = {
6841f3bbfd8SEd Schouten 	X(SOCKSTATE_ACCEPTCONN)
685808d9805SEd Schouten 	XEND
686808d9805SEd Schouten };
687808d9805SEd Schouten 
688808d9805SEd Schouten static struct xlat cloudabi_ulflags[] = {
689808d9805SEd Schouten 	X(UNLINK_REMOVEDIR)
690808d9805SEd Schouten 	XEND
691808d9805SEd Schouten };
692808d9805SEd Schouten 
693808d9805SEd Schouten static struct xlat cloudabi_whence[] = {
694808d9805SEd Schouten 	X(WHENCE_CUR) X(WHENCE_END) X(WHENCE_SET)
695808d9805SEd Schouten 	XEND
696808d9805SEd Schouten };
697808d9805SEd Schouten 
698808d9805SEd Schouten #undef X
699081e5c48SPav Lucistnik #undef XEND
700081e5c48SPav Lucistnik 
701d8984f48SDag-Erling Smørgrav /*
702d8984f48SDag-Erling Smørgrav  * Searches an xlat array for a value, and returns it if found.  Otherwise
703d8984f48SDag-Erling Smørgrav  * return a string representation.
704d8984f48SDag-Erling Smørgrav  */
705d8984f48SDag-Erling Smørgrav static const char *
706d8984f48SDag-Erling Smørgrav lookup(struct xlat *xlat, int val, int base)
707081e5c48SPav Lucistnik {
708081e5c48SPav Lucistnik 	static char tmp[16];
709d8984f48SDag-Erling Smørgrav 
710081e5c48SPav Lucistnik 	for (; xlat->str != NULL; xlat++)
711081e5c48SPav Lucistnik 		if (xlat->val == val)
712d8984f48SDag-Erling Smørgrav 			return (xlat->str);
713081e5c48SPav Lucistnik 	switch (base) {
714081e5c48SPav Lucistnik 		case 8:
715081e5c48SPav Lucistnik 			sprintf(tmp, "0%o", val);
716081e5c48SPav Lucistnik 			break;
717081e5c48SPav Lucistnik 		case 16:
718081e5c48SPav Lucistnik 			sprintf(tmp, "0x%x", val);
719081e5c48SPav Lucistnik 			break;
720081e5c48SPav Lucistnik 		case 10:
721081e5c48SPav Lucistnik 			sprintf(tmp, "%u", val);
722081e5c48SPav Lucistnik 			break;
723081e5c48SPav Lucistnik 		default:
724081e5c48SPav Lucistnik 			errx(1,"Unknown lookup base");
725081e5c48SPav Lucistnik 			break;
726081e5c48SPav Lucistnik 	}
727d8984f48SDag-Erling Smørgrav 	return (tmp);
728081e5c48SPav Lucistnik }
729081e5c48SPav Lucistnik 
7305d2d083cSXin LI static const char *
7315d2d083cSXin LI xlookup(struct xlat *xlat, int val)
732081e5c48SPav Lucistnik {
733d8984f48SDag-Erling Smørgrav 
734d8984f48SDag-Erling Smørgrav 	return (lookup(xlat, val, 16));
735081e5c48SPav Lucistnik }
736081e5c48SPav Lucistnik 
7374e3da534SJohn Baldwin /*
7384e3da534SJohn Baldwin  * Searches an xlat array containing bitfield values.  Remaining bits
7394e3da534SJohn Baldwin  * set after removing the known ones are printed at the end:
7404e3da534SJohn Baldwin  * IN|0x400.
7414e3da534SJohn Baldwin  */
742d8984f48SDag-Erling Smørgrav static char *
743d8984f48SDag-Erling Smørgrav xlookup_bits(struct xlat *xlat, int val)
744081e5c48SPav Lucistnik {
74594355cfdSAndrey Zonov 	int len, rem;
746081e5c48SPav Lucistnik 	static char str[512];
747081e5c48SPav Lucistnik 
74894355cfdSAndrey Zonov 	len = 0;
74994355cfdSAndrey Zonov 	rem = val;
750d8984f48SDag-Erling Smørgrav 	for (; xlat->str != NULL; xlat++) {
751d8984f48SDag-Erling Smørgrav 		if ((xlat->val & rem) == xlat->val) {
7524e3da534SJohn Baldwin 			/*
7534e3da534SJohn Baldwin 			 * Don't print the "all-bits-zero" string unless all
7544e3da534SJohn Baldwin 			 * bits are really zero.
7554e3da534SJohn Baldwin 			 */
756081e5c48SPav Lucistnik 			if (xlat->val == 0 && val != 0)
757081e5c48SPav Lucistnik 				continue;
758081e5c48SPav Lucistnik 			len += sprintf(str + len, "%s|", xlat->str);
759081e5c48SPav Lucistnik 			rem &= ~(xlat->val);
760081e5c48SPav Lucistnik 		}
761081e5c48SPav Lucistnik 	}
7624e3da534SJohn Baldwin 
7634e3da534SJohn Baldwin 	/*
7644e3da534SJohn Baldwin 	 * If we have leftover bits or didn't match anything, print
7654e3da534SJohn Baldwin 	 * the remainder.
7664e3da534SJohn Baldwin 	 */
767081e5c48SPav Lucistnik 	if (rem || len == 0)
768081e5c48SPav Lucistnik 		len += sprintf(str + len, "0x%x", rem);
769081e5c48SPav Lucistnik 	if (len && str[len - 1] == '|')
770081e5c48SPav Lucistnik 		len--;
771081e5c48SPav Lucistnik 	str[len] = 0;
772d8984f48SDag-Erling Smørgrav 	return (str);
773081e5c48SPav Lucistnik }
774081e5c48SPav Lucistnik 
7759289f547SJohn Baldwin static void
7769289f547SJohn Baldwin print_integer_arg(const char *(*decoder)(int), FILE *fp, int value)
7779289f547SJohn Baldwin {
7789289f547SJohn Baldwin 	const char *str;
7799289f547SJohn Baldwin 
7809289f547SJohn Baldwin 	str = decoder(value);
7819289f547SJohn Baldwin 	if (str != NULL)
7829289f547SJohn Baldwin 		fputs(str, fp);
7839289f547SJohn Baldwin 	else
7849289f547SJohn Baldwin 		fprintf(fp, "%d", value);
7859289f547SJohn Baldwin }
7869289f547SJohn Baldwin 
7879289f547SJohn Baldwin static void
7889289f547SJohn Baldwin print_mask_arg(bool (*decoder)(FILE *, int, int *), FILE *fp, int value)
7899289f547SJohn Baldwin {
7909289f547SJohn Baldwin 	int rem;
7919289f547SJohn Baldwin 
7929289f547SJohn Baldwin 	if (!decoder(fp, value, &rem))
7939289f547SJohn Baldwin 		fprintf(fp, "0x%x", rem);
7949289f547SJohn Baldwin 	else if (rem != 0)
7959289f547SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
7969289f547SJohn Baldwin }
7979289f547SJohn Baldwin 
798*bed418c8SJohn Baldwin static void
799*bed418c8SJohn Baldwin print_mask_arg32(bool (*decoder)(FILE *, uint32_t, uint32_t *), FILE *fp,
800*bed418c8SJohn Baldwin     uint32_t value)
801*bed418c8SJohn Baldwin {
802*bed418c8SJohn Baldwin 	uint32_t rem;
803*bed418c8SJohn Baldwin 
804*bed418c8SJohn Baldwin 	if (!decoder(fp, value, &rem))
805*bed418c8SJohn Baldwin 		fprintf(fp, "0x%x", rem);
806*bed418c8SJohn Baldwin 	else if (rem != 0)
807*bed418c8SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
808*bed418c8SJohn Baldwin }
809*bed418c8SJohn Baldwin 
810c05cc0d6SJohn Baldwin #ifndef __LP64__
811c05cc0d6SJohn Baldwin /*
812c05cc0d6SJohn Baldwin  * Add argument padding to subsequent system calls afater a Quad
813c05cc0d6SJohn Baldwin  * syscall arguments as needed.  This used to be done by hand in the
814c05cc0d6SJohn Baldwin  * decoded_syscalls table which was ugly and error prone.  It is
815c05cc0d6SJohn Baldwin  * simpler to do the fixup of offsets at initalization time than when
816c05cc0d6SJohn Baldwin  * decoding arguments.
817c05cc0d6SJohn Baldwin  */
818c05cc0d6SJohn Baldwin static void
819c05cc0d6SJohn Baldwin quad_fixup(struct syscall *sc)
820c05cc0d6SJohn Baldwin {
821c05cc0d6SJohn Baldwin 	int offset, prev;
822c05cc0d6SJohn Baldwin 	u_int i;
823c05cc0d6SJohn Baldwin 
824c05cc0d6SJohn Baldwin 	offset = 0;
825c05cc0d6SJohn Baldwin 	prev = -1;
826c05cc0d6SJohn Baldwin 	for (i = 0; i < sc->nargs; i++) {
827c05cc0d6SJohn Baldwin 		/* This arg type is a dummy that doesn't use offset. */
828c05cc0d6SJohn Baldwin 		if ((sc->args[i].type & ARG_MASK) == PipeFds)
829c05cc0d6SJohn Baldwin 			continue;
830c05cc0d6SJohn Baldwin 
831c05cc0d6SJohn Baldwin 		assert(prev < sc->args[i].offset);
832c05cc0d6SJohn Baldwin 		prev = sc->args[i].offset;
833c05cc0d6SJohn Baldwin 		sc->args[i].offset += offset;
834c05cc0d6SJohn Baldwin 		switch (sc->args[i].type & ARG_MASK) {
835c05cc0d6SJohn Baldwin 		case Quad:
836c05cc0d6SJohn Baldwin 		case QuadHex:
837c05cc0d6SJohn Baldwin #ifdef __powerpc__
838c05cc0d6SJohn Baldwin 			/*
839c05cc0d6SJohn Baldwin 			 * 64-bit arguments on 32-bit powerpc must be
840c05cc0d6SJohn Baldwin 			 * 64-bit aligned.  If the current offset is
841c05cc0d6SJohn Baldwin 			 * not aligned, the calling convention inserts
842c05cc0d6SJohn Baldwin 			 * a 32-bit pad argument that should be skipped.
843c05cc0d6SJohn Baldwin 			 */
844c05cc0d6SJohn Baldwin 			if (sc->args[i].offset % 2 == 1) {
845c05cc0d6SJohn Baldwin 				sc->args[i].offset++;
846c05cc0d6SJohn Baldwin 				offset++;
847c05cc0d6SJohn Baldwin 			}
848c05cc0d6SJohn Baldwin #endif
849c05cc0d6SJohn Baldwin 			offset++;
850c05cc0d6SJohn Baldwin 		default:
851c05cc0d6SJohn Baldwin 			break;
852c05cc0d6SJohn Baldwin 		}
853c05cc0d6SJohn Baldwin 	}
854c05cc0d6SJohn Baldwin }
855c05cc0d6SJohn Baldwin #endif
856c05cc0d6SJohn Baldwin 
8576c61b0f3SBryan Drewery void
8586c61b0f3SBryan Drewery init_syscalls(void)
8596c61b0f3SBryan Drewery {
8606c61b0f3SBryan Drewery 	struct syscall *sc;
8616c61b0f3SBryan Drewery 
8626c61b0f3SBryan Drewery 	STAILQ_INIT(&syscalls);
863c05cc0d6SJohn Baldwin 	for (sc = decoded_syscalls; sc->name != NULL; sc++) {
864c05cc0d6SJohn Baldwin #ifndef __LP64__
865c05cc0d6SJohn Baldwin 		quad_fixup(sc);
866c05cc0d6SJohn Baldwin #endif
8676c61b0f3SBryan Drewery 		STAILQ_INSERT_HEAD(&syscalls, sc, entries);
8686c61b0f3SBryan Drewery 	}
869c05cc0d6SJohn Baldwin }
8701175b23fSJohn Baldwin 
8711175b23fSJohn Baldwin static struct syscall *
8721175b23fSJohn Baldwin find_syscall(struct procabi *abi, u_int number)
8731175b23fSJohn Baldwin {
8741175b23fSJohn Baldwin 	struct extra_syscall *es;
8751175b23fSJohn Baldwin 
8761175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls))
8771175b23fSJohn Baldwin 		return (abi->syscalls[number]);
8781175b23fSJohn Baldwin 	STAILQ_FOREACH(es, &abi->extra_syscalls, entries) {
8791175b23fSJohn Baldwin 		if (es->number == number)
8801175b23fSJohn Baldwin 			return (es->sc);
8811175b23fSJohn Baldwin 	}
8821175b23fSJohn Baldwin 	return (NULL);
8831175b23fSJohn Baldwin }
8841175b23fSJohn Baldwin 
8851175b23fSJohn Baldwin static void
8861175b23fSJohn Baldwin add_syscall(struct procabi *abi, u_int number, struct syscall *sc)
8871175b23fSJohn Baldwin {
8881175b23fSJohn Baldwin 	struct extra_syscall *es;
8891175b23fSJohn Baldwin 
8901175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls)) {
8911175b23fSJohn Baldwin 		assert(abi->syscalls[number] == NULL);
8921175b23fSJohn Baldwin 		abi->syscalls[number] = sc;
8931175b23fSJohn Baldwin 	} else {
8941175b23fSJohn Baldwin 		es = malloc(sizeof(*es));
8951175b23fSJohn Baldwin 		es->sc = sc;
8961175b23fSJohn Baldwin 		es->number = number;
8971175b23fSJohn Baldwin 		STAILQ_INSERT_TAIL(&abi->extra_syscalls, es, entries);
8981175b23fSJohn Baldwin 	}
8991175b23fSJohn Baldwin }
9001175b23fSJohn Baldwin 
901bbeaf6c0SSean Eric Fagan /*
902bbeaf6c0SSean Eric Fagan  * If/when the list gets big, it might be desirable to do it
903bbeaf6c0SSean Eric Fagan  * as a hash table or binary search.
904bbeaf6c0SSean Eric Fagan  */
905bbeaf6c0SSean Eric Fagan struct syscall *
9061175b23fSJohn Baldwin get_syscall(struct threadinfo *t, u_int number, u_int nargs)
907d8984f48SDag-Erling Smørgrav {
90894355cfdSAndrey Zonov 	struct syscall *sc;
9091175b23fSJohn Baldwin 	const char *name;
9101175b23fSJohn Baldwin 	char *new_name;
9111175b23fSJohn Baldwin 	u_int i;
912bbeaf6c0SSean Eric Fagan 
9131175b23fSJohn Baldwin 	sc = find_syscall(t->proc->abi, number);
9141175b23fSJohn Baldwin 	if (sc != NULL)
915d8984f48SDag-Erling Smørgrav 		return (sc);
9166c61b0f3SBryan Drewery 
9171175b23fSJohn Baldwin 	name = sysdecode_syscallname(t->proc->abi->abi, number);
9181175b23fSJohn Baldwin 	if (name == NULL) {
9191175b23fSJohn Baldwin 		asprintf(&new_name, "#%d", number);
9201175b23fSJohn Baldwin 		name = new_name;
9211175b23fSJohn Baldwin 	} else
9221175b23fSJohn Baldwin 		new_name = NULL;
9231175b23fSJohn Baldwin 	STAILQ_FOREACH(sc, &syscalls, entries) {
9241175b23fSJohn Baldwin 		if (strcmp(name, sc->name) == 0) {
9251175b23fSJohn Baldwin 			add_syscall(t->proc->abi, number, sc);
9261175b23fSJohn Baldwin 			free(new_name);
9271175b23fSJohn Baldwin 			return (sc);
9281175b23fSJohn Baldwin 		}
9291175b23fSJohn Baldwin 	}
9301175b23fSJohn Baldwin 
9316c61b0f3SBryan Drewery 	/* It is unknown.  Add it into the list. */
9326c61b0f3SBryan Drewery #if DEBUG
9336c61b0f3SBryan Drewery 	fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
9346c61b0f3SBryan Drewery 	    nargs);
9356c61b0f3SBryan Drewery #endif
9366c61b0f3SBryan Drewery 
9376c61b0f3SBryan Drewery 	sc = calloc(1, sizeof(struct syscall));
9381175b23fSJohn Baldwin 	sc->name = name;
9391175b23fSJohn Baldwin 	if (new_name != NULL)
9401175b23fSJohn Baldwin 		sc->unknown = true;
9416c61b0f3SBryan Drewery 	sc->ret_type = 1;
9426c61b0f3SBryan Drewery 	sc->nargs = nargs;
9436c61b0f3SBryan Drewery 	for (i = 0; i < nargs; i++) {
9446c61b0f3SBryan Drewery 		sc->args[i].offset = i;
9456c61b0f3SBryan Drewery 		/* Treat all unknown arguments as LongHex. */
9466c61b0f3SBryan Drewery 		sc->args[i].type = LongHex;
947bbeaf6c0SSean Eric Fagan 	}
9486c61b0f3SBryan Drewery 	STAILQ_INSERT_HEAD(&syscalls, sc, entries);
9491175b23fSJohn Baldwin 	add_syscall(t->proc->abi, number, sc);
9506c61b0f3SBryan Drewery 
9516c61b0f3SBryan Drewery 	return (sc);
952bbeaf6c0SSean Eric Fagan }
953bbeaf6c0SSean Eric Fagan 
954bbeaf6c0SSean Eric Fagan /*
9559ddd1412SDag-Erling Smørgrav  * Copy a fixed amount of bytes from the process.
9569ddd1412SDag-Erling Smørgrav  */
9571be5d704SMark Murray static int
958be305c9cSAndrey Zonov get_struct(pid_t pid, void *offset, void *buf, int len)
959d8984f48SDag-Erling Smørgrav {
9605d2d083cSXin LI 	struct ptrace_io_desc iorequest;
9619ddd1412SDag-Erling Smørgrav 
9625d2d083cSXin LI 	iorequest.piod_op = PIOD_READ_D;
9635d2d083cSXin LI 	iorequest.piod_offs = offset;
9645d2d083cSXin LI 	iorequest.piod_addr = buf;
9655d2d083cSXin LI 	iorequest.piod_len = len;
9665d2d083cSXin LI 	if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0)
967d8984f48SDag-Erling Smørgrav 		return (-1);
968d8984f48SDag-Erling Smørgrav 	return (0);
9699ddd1412SDag-Erling Smørgrav }
9709ddd1412SDag-Erling Smørgrav 
9715d2d083cSXin LI #define	MAXSIZE		4096
972abb3f965SJohn Baldwin 
9739ddd1412SDag-Erling Smørgrav /*
974bbeaf6c0SSean Eric Fagan  * Copy a string from the process.  Note that it is
975bbeaf6c0SSean Eric Fagan  * expected to be a C string, but if max is set, it will
976bbeaf6c0SSean Eric Fagan  * only get that much.
977bbeaf6c0SSean Eric Fagan  */
9785d2d083cSXin LI static char *
979abb3f965SJohn Baldwin get_string(pid_t pid, void *addr, int max)
980d8984f48SDag-Erling Smørgrav {
9815d2d083cSXin LI 	struct ptrace_io_desc iorequest;
982abb3f965SJohn Baldwin 	char *buf, *nbuf;
983abb3f965SJohn Baldwin 	size_t offset, size, totalsize;
984bbeaf6c0SSean Eric Fagan 
985abb3f965SJohn Baldwin 	offset = 0;
986abb3f965SJohn Baldwin 	if (max)
987abb3f965SJohn Baldwin 		size = max + 1;
988abb3f965SJohn Baldwin 	else {
989abb3f965SJohn Baldwin 		/* Read up to the end of the current page. */
990abb3f965SJohn Baldwin 		size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE);
991abb3f965SJohn Baldwin 		if (size > MAXSIZE)
992abb3f965SJohn Baldwin 			size = MAXSIZE;
993abb3f965SJohn Baldwin 	}
994abb3f965SJohn Baldwin 	totalsize = size;
9955d2d083cSXin LI 	buf = malloc(totalsize);
9965d2d083cSXin LI 	if (buf == NULL)
997d8984f48SDag-Erling Smørgrav 		return (NULL);
9985d2d083cSXin LI 	for (;;) {
9995d2d083cSXin LI 		iorequest.piod_op = PIOD_READ_D;
1000abb3f965SJohn Baldwin 		iorequest.piod_offs = (char *)addr + offset;
1001abb3f965SJohn Baldwin 		iorequest.piod_addr = buf + offset;
10025d2d083cSXin LI 		iorequest.piod_len = size;
10035d2d083cSXin LI 		if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) {
10045d2d083cSXin LI 			free(buf);
1005d8984f48SDag-Erling Smørgrav 			return (NULL);
1006bbeaf6c0SSean Eric Fagan 		}
1007abb3f965SJohn Baldwin 		if (memchr(buf + offset, '\0', size) != NULL)
1008abb3f965SJohn Baldwin 			return (buf);
1009abb3f965SJohn Baldwin 		offset += size;
1010abb3f965SJohn Baldwin 		if (totalsize < MAXSIZE && max == 0) {
1011abb3f965SJohn Baldwin 			size = MAXSIZE - totalsize;
1012abb3f965SJohn Baldwin 			if (size > PAGE_SIZE)
1013abb3f965SJohn Baldwin 				size = PAGE_SIZE;
1014abb3f965SJohn Baldwin 			nbuf = realloc(buf, totalsize + size);
1015abb3f965SJohn Baldwin 			if (nbuf == NULL) {
1016abb3f965SJohn Baldwin 				buf[totalsize - 1] = '\0';
10174e92419dSMarcel Moolenaar 				return (buf);
1018bbeaf6c0SSean Eric Fagan 			}
1019abb3f965SJohn Baldwin 			buf = nbuf;
1020abb3f965SJohn Baldwin 			totalsize += size;
1021d8984f48SDag-Erling Smørgrav 		} else {
1022cdfc719cSJaakko Heinonen 			buf[totalsize - 1] = '\0';
1023d8984f48SDag-Erling Smørgrav 			return (buf);
10245d2d083cSXin LI 		}
10255d2d083cSXin LI 	}
10265d2d083cSXin LI }
1027bbeaf6c0SSean Eric Fagan 
10289289f547SJohn Baldwin static const char *
102934763d1cSJohn Baldwin strsig2(int sig)
103034763d1cSJohn Baldwin {
10319289f547SJohn Baldwin 	static char tmp[32];
10329289f547SJohn Baldwin 	const char *signame;
103334763d1cSJohn Baldwin 
10349289f547SJohn Baldwin 	signame = sysdecode_signal(sig);
10359289f547SJohn Baldwin 	if (signame == NULL) {
1036f083f689SJohn Baldwin 		snprintf(tmp, sizeof(tmp), "%d", sig);
10379289f547SJohn Baldwin 		signame = tmp;
1038f083f689SJohn Baldwin 	}
10399289f547SJohn Baldwin 	return (signame);
104034763d1cSJohn Baldwin }
1041bbeaf6c0SSean Eric Fagan 
1042c915ff03SJohn Baldwin static void
1043c915ff03SJohn Baldwin print_kevent(FILE *fp, struct kevent *ke, int input)
1044c915ff03SJohn Baldwin {
1045c915ff03SJohn Baldwin 
1046c915ff03SJohn Baldwin 	switch (ke->filter) {
1047c915ff03SJohn Baldwin 	case EVFILT_READ:
1048c915ff03SJohn Baldwin 	case EVFILT_WRITE:
1049c915ff03SJohn Baldwin 	case EVFILT_VNODE:
1050c915ff03SJohn Baldwin 	case EVFILT_PROC:
1051c915ff03SJohn Baldwin 	case EVFILT_TIMER:
1052c915ff03SJohn Baldwin 	case EVFILT_PROCDESC:
1053c915ff03SJohn Baldwin 		fprintf(fp, "%ju", (uintmax_t)ke->ident);
1054c915ff03SJohn Baldwin 		break;
1055c915ff03SJohn Baldwin 	case EVFILT_SIGNAL:
1056c915ff03SJohn Baldwin 		fputs(strsig2(ke->ident), fp);
1057c915ff03SJohn Baldwin 		break;
1058c915ff03SJohn Baldwin 	default:
1059c915ff03SJohn Baldwin 		fprintf(fp, "%p", (void *)ke->ident);
1060c915ff03SJohn Baldwin 	}
1061c915ff03SJohn Baldwin 	fprintf(fp, ",%s,%s,", xlookup(kevent_filters, ke->filter),
1062c915ff03SJohn Baldwin 	    xlookup_bits(kevent_flags, ke->flags));
1063c915ff03SJohn Baldwin 	switch (ke->filter) {
1064c915ff03SJohn Baldwin 	case EVFILT_READ:
1065c915ff03SJohn Baldwin 	case EVFILT_WRITE:
1066c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_rdwr_fflags, ke->fflags), fp);
1067c915ff03SJohn Baldwin 		break;
1068c915ff03SJohn Baldwin 	case EVFILT_VNODE:
1069c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_vnode_fflags, ke->fflags), fp);
1070c915ff03SJohn Baldwin 		break;
1071c915ff03SJohn Baldwin 	case EVFILT_PROC:
1072c915ff03SJohn Baldwin 	case EVFILT_PROCDESC:
1073c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_proc_fflags, ke->fflags), fp);
1074c915ff03SJohn Baldwin 		break;
1075c915ff03SJohn Baldwin 	case EVFILT_TIMER:
1076c915ff03SJohn Baldwin 		fputs(xlookup_bits(kevent_timer_fflags, ke->fflags), fp);
1077c915ff03SJohn Baldwin 		break;
1078c915ff03SJohn Baldwin 	case EVFILT_USER: {
1079c915ff03SJohn Baldwin 		int ctrl, data;
1080c915ff03SJohn Baldwin 
1081c915ff03SJohn Baldwin 		ctrl = ke->fflags & NOTE_FFCTRLMASK;
1082c915ff03SJohn Baldwin 		data = ke->fflags & NOTE_FFLAGSMASK;
1083c915ff03SJohn Baldwin 		if (input) {
1084c915ff03SJohn Baldwin 			fputs(xlookup(kevent_user_ffctrl, ctrl), fp);
1085c915ff03SJohn Baldwin 			if (ke->fflags & NOTE_TRIGGER)
1086c915ff03SJohn Baldwin 				fputs("|NOTE_TRIGGER", fp);
1087c915ff03SJohn Baldwin 			if (data != 0)
1088c915ff03SJohn Baldwin 				fprintf(fp, "|%#x", data);
1089c915ff03SJohn Baldwin 		} else {
1090c915ff03SJohn Baldwin 			fprintf(fp, "%#x", data);
1091c915ff03SJohn Baldwin 		}
1092c915ff03SJohn Baldwin 		break;
1093c915ff03SJohn Baldwin 	}
1094c915ff03SJohn Baldwin 	default:
1095c915ff03SJohn Baldwin 		fprintf(fp, "%#x", ke->fflags);
1096c915ff03SJohn Baldwin 	}
1097c915ff03SJohn Baldwin 	fprintf(fp, ",%p,%p", (void *)ke->data, (void *)ke->udata);
1098c915ff03SJohn Baldwin }
1099c915ff03SJohn Baldwin 
1100195aef99SBryan Drewery static void
1101195aef99SBryan Drewery print_utrace(FILE *fp, void *utrace_addr, size_t len)
1102195aef99SBryan Drewery {
1103195aef99SBryan Drewery 	unsigned char *utrace_buffer;
1104195aef99SBryan Drewery 
1105195aef99SBryan Drewery 	fprintf(fp, "{ ");
1106d6fb4894SJohn Baldwin 	if (sysdecode_utrace(fp, utrace_addr, len)) {
1107195aef99SBryan Drewery 		fprintf(fp, " }");
1108195aef99SBryan Drewery 		return;
1109195aef99SBryan Drewery 	}
1110195aef99SBryan Drewery 
1111195aef99SBryan Drewery 	utrace_buffer = utrace_addr;
1112195aef99SBryan Drewery 	fprintf(fp, "%zu:", len);
1113195aef99SBryan Drewery 	while (len--)
1114195aef99SBryan Drewery 		fprintf(fp, " %02x", *utrace_buffer++);
1115195aef99SBryan Drewery 	fprintf(fp, " }");
1116195aef99SBryan Drewery }
1117195aef99SBryan Drewery 
1118bbeaf6c0SSean Eric Fagan /*
1119bbeaf6c0SSean Eric Fagan  * Converts a syscall argument into a string.  Said string is
11204e3da534SJohn Baldwin  * allocated via malloc(), so needs to be free()'d.  sc is
1121bbeaf6c0SSean Eric Fagan  * a pointer to the syscall description (see above); args is
1122bbeaf6c0SSean Eric Fagan  * an array of all of the system call arguments.
1123bbeaf6c0SSean Eric Fagan  */
1124bbeaf6c0SSean Eric Fagan char *
11252b75c8adSJohn Baldwin print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
112694355cfdSAndrey Zonov     struct trussinfo *trussinfo)
1127d8984f48SDag-Erling Smørgrav {
1128f083f689SJohn Baldwin 	FILE *fp;
112994355cfdSAndrey Zonov 	char *tmp;
1130f083f689SJohn Baldwin 	size_t tmplen;
113194355cfdSAndrey Zonov 	pid_t pid;
1132d8984f48SDag-Erling Smørgrav 
1133f083f689SJohn Baldwin 	fp = open_memstream(&tmp, &tmplen);
11342b75c8adSJohn Baldwin 	pid = trussinfo->curthread->proc->pid;
1135bbeaf6c0SSean Eric Fagan 	switch (sc->type & ARG_MASK) {
1136bbeaf6c0SSean Eric Fagan 	case Hex:
1137f083f689SJohn Baldwin 		fprintf(fp, "0x%x", (int)args[sc->offset]);
1138bbeaf6c0SSean Eric Fagan 		break;
1139bbeaf6c0SSean Eric Fagan 	case Octal:
1140f083f689SJohn Baldwin 		fprintf(fp, "0%o", (int)args[sc->offset]);
1141bbeaf6c0SSean Eric Fagan 		break;
1142bbeaf6c0SSean Eric Fagan 	case Int:
1143f083f689SJohn Baldwin 		fprintf(fp, "%d", (int)args[sc->offset]);
1144bbeaf6c0SSean Eric Fagan 		break;
1145808d9805SEd Schouten 	case UInt:
1146808d9805SEd Schouten 		fprintf(fp, "%u", (unsigned int)args[sc->offset]);
1147808d9805SEd Schouten 		break;
1148fdb5bf37SJohn Baldwin 	case LongHex:
1149f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
1150fdb5bf37SJohn Baldwin 		break;
1151b289a8d7SJohn Baldwin 	case Long:
1152f083f689SJohn Baldwin 		fprintf(fp, "%ld", args[sc->offset]);
1153b289a8d7SJohn Baldwin 		break;
1154d8984f48SDag-Erling Smørgrav 	case Name: {
1155081e5c48SPav Lucistnik 		/* NULL-terminated string. */
1156bbeaf6c0SSean Eric Fagan 		char *tmp2;
11574e3da534SJohn Baldwin 
11585d2d083cSXin LI 		tmp2 = get_string(pid, (void*)args[sc->offset], 0);
1159f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
1160bbeaf6c0SSean Eric Fagan 		free(tmp2);
1161bbeaf6c0SSean Eric Fagan 		break;
1162d8984f48SDag-Erling Smørgrav 	}
1163d8984f48SDag-Erling Smørgrav 	case BinString: {
11644e3da534SJohn Baldwin 		/*
11654e3da534SJohn Baldwin 		 * Binary block of data that might have printable characters.
11664e3da534SJohn Baldwin 		 * XXX If type|OUT, assume that the length is the syscall's
11674e3da534SJohn Baldwin 		 * return value.  Otherwise, assume that the length of the block
11684e3da534SJohn Baldwin 		 * is in the next syscall argument.
11694e3da534SJohn Baldwin 		 */
1170081e5c48SPav Lucistnik 		int max_string = trussinfo->strsize;
1171081e5c48SPav Lucistnik 		char tmp2[max_string + 1], *tmp3;
1172081e5c48SPav Lucistnik 		int len;
1173081e5c48SPav Lucistnik 		int truncated = 0;
1174081e5c48SPav Lucistnik 
1175081e5c48SPav Lucistnik 		if (sc->type & OUT)
11762b75c8adSJohn Baldwin 			len = retval[0];
1177081e5c48SPav Lucistnik 		else
1178081e5c48SPav Lucistnik 			len = args[sc->offset + 1];
1179081e5c48SPav Lucistnik 
11804e3da534SJohn Baldwin 		/*
11814e3da534SJohn Baldwin 		 * Don't print more than max_string characters, to avoid word
11824e3da534SJohn Baldwin 		 * wrap.  If we have to truncate put some ... after the string.
1183081e5c48SPav Lucistnik 		 */
1184081e5c48SPav Lucistnik 		if (len > max_string) {
1185081e5c48SPav Lucistnik 			len = max_string;
1186081e5c48SPav Lucistnik 			truncated = 1;
1187081e5c48SPav Lucistnik 		}
118894355cfdSAndrey Zonov 		if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len)
118994355cfdSAndrey Zonov 		    != -1) {
1190081e5c48SPav Lucistnik 			tmp3 = malloc(len * 4 + 1);
1191081e5c48SPav Lucistnik 			while (len) {
119294355cfdSAndrey Zonov 				if (strvisx(tmp3, tmp2, len,
119394355cfdSAndrey Zonov 				    VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
1194081e5c48SPav Lucistnik 					break;
1195081e5c48SPav Lucistnik 				len--;
1196081e5c48SPav Lucistnik 				truncated = 1;
119780c7cc1cSPedro F. Giffuni 			}
1198f083f689SJohn Baldwin 			fprintf(fp, "\"%s\"%s", tmp3, truncated ?
119994355cfdSAndrey Zonov 			    "..." : "");
1200081e5c48SPav Lucistnik 			free(tmp3);
1201d8984f48SDag-Erling Smørgrav 		} else {
1202f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1203081e5c48SPav Lucistnik 		}
1204081e5c48SPav Lucistnik 		break;
1205d8984f48SDag-Erling Smørgrav 	}
120668055893SJohn Baldwin 	case ExecArgs:
120768055893SJohn Baldwin 	case ExecEnv:
1208d8984f48SDag-Erling Smørgrav 	case StringArray: {
1209890843c1SJohn Baldwin 		uintptr_t addr;
1210890843c1SJohn Baldwin 		union {
1211890843c1SJohn Baldwin 			char *strarray[0];
1212890843c1SJohn Baldwin 			char buf[PAGE_SIZE];
1213890843c1SJohn Baldwin 		} u;
12149897b203SMatthew N. Dodd 		char *string;
1215890843c1SJohn Baldwin 		size_t len;
12162b75c8adSJohn Baldwin 		u_int first, i;
12179897b203SMatthew N. Dodd 
1218890843c1SJohn Baldwin 		/*
121968055893SJohn Baldwin 		 * Only parse argv[] and environment arrays from exec calls
122068055893SJohn Baldwin 		 * if requested.
122168055893SJohn Baldwin 		 */
122268055893SJohn Baldwin 		if (((sc->type & ARG_MASK) == ExecArgs &&
122368055893SJohn Baldwin 		    (trussinfo->flags & EXECVEARGS) == 0) ||
122468055893SJohn Baldwin 		    ((sc->type & ARG_MASK) == ExecEnv &&
122568055893SJohn Baldwin 		    (trussinfo->flags & EXECVEENVS) == 0)) {
122668055893SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
122768055893SJohn Baldwin 			break;
122868055893SJohn Baldwin 		}
122968055893SJohn Baldwin 
123068055893SJohn Baldwin 		/*
1231890843c1SJohn Baldwin 		 * Read a page of pointers at a time.  Punt if the top-level
1232890843c1SJohn Baldwin 		 * pointer is not aligned.  Note that the first read is of
1233890843c1SJohn Baldwin 		 * a partial page.
1234890843c1SJohn Baldwin 		 */
1235890843c1SJohn Baldwin 		addr = args[sc->offset];
1236890843c1SJohn Baldwin 		if (addr % sizeof(char *) != 0) {
1237890843c1SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1238890843c1SJohn Baldwin 			break;
12399897b203SMatthew N. Dodd 		}
12409897b203SMatthew N. Dodd 
1241890843c1SJohn Baldwin 		len = PAGE_SIZE - (addr & PAGE_MASK);
1242890843c1SJohn Baldwin 		if (get_struct(pid, (void *)addr, u.buf, len) == -1) {
1243890843c1SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1244890843c1SJohn Baldwin 			break;
12459897b203SMatthew N. Dodd 		}
1246890843c1SJohn Baldwin 
1247890843c1SJohn Baldwin 		fputc('[', fp);
1248890843c1SJohn Baldwin 		first = 1;
1249890843c1SJohn Baldwin 		i = 0;
1250890843c1SJohn Baldwin 		while (u.strarray[i] != NULL) {
1251890843c1SJohn Baldwin 			string = get_string(pid, u.strarray[i], 0);
1252890843c1SJohn Baldwin 			fprintf(fp, "%s \"%s\"", first ? "" : ",", string);
1253890843c1SJohn Baldwin 			free(string);
1254890843c1SJohn Baldwin 			first = 0;
1255890843c1SJohn Baldwin 
1256890843c1SJohn Baldwin 			i++;
1257890843c1SJohn Baldwin 			if (i == len / sizeof(char *)) {
1258890843c1SJohn Baldwin 				addr += len;
1259890843c1SJohn Baldwin 				len = PAGE_SIZE;
1260890843c1SJohn Baldwin 				if (get_struct(pid, (void *)addr, u.buf, len) ==
1261890843c1SJohn Baldwin 				    -1) {
1262890843c1SJohn Baldwin 					fprintf(fp, ", <inval>");
1263890843c1SJohn Baldwin 					break;
1264890843c1SJohn Baldwin 				}
1265890843c1SJohn Baldwin 				i = 0;
1266890843c1SJohn Baldwin 			}
1267890843c1SJohn Baldwin 		}
1268890843c1SJohn Baldwin 		fputs(" ]", fp);
12699897b203SMatthew N. Dodd 		break;
1270d8984f48SDag-Erling Smørgrav 	}
127110aeefc9SMarcel Moolenaar #ifdef __LP64__
127210aeefc9SMarcel Moolenaar 	case Quad:
127372df19e7SJohn Baldwin 		fprintf(fp, "%ld", args[sc->offset]);
127472df19e7SJohn Baldwin 		break;
127572df19e7SJohn Baldwin 	case QuadHex:
1276f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
127710aeefc9SMarcel Moolenaar 		break;
127810aeefc9SMarcel Moolenaar #else
127972df19e7SJohn Baldwin 	case Quad:
128072df19e7SJohn Baldwin 	case QuadHex: {
128110aeefc9SMarcel Moolenaar 		unsigned long long ll;
12824e3da534SJohn Baldwin 
12832b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
12842b75c8adSJohn Baldwin 		ll = (unsigned long long)args[sc->offset + 1] << 32 |
12852b75c8adSJohn Baldwin 		    args[sc->offset];
12862b75c8adSJohn Baldwin #else
12872b75c8adSJohn Baldwin 		ll = (unsigned long long)args[sc->offset] << 32 |
12882b75c8adSJohn Baldwin 		    args[sc->offset + 1];
12892b75c8adSJohn Baldwin #endif
129072df19e7SJohn Baldwin 		if ((sc->type & ARG_MASK) == Quad)
129172df19e7SJohn Baldwin 			fprintf(fp, "%lld", ll);
129272df19e7SJohn Baldwin 		else
1293f083f689SJohn Baldwin 			fprintf(fp, "0x%llx", ll);
1294bbeaf6c0SSean Eric Fagan 		break;
1295bbeaf6c0SSean Eric Fagan 	}
129610aeefc9SMarcel Moolenaar #endif
1297bbeaf6c0SSean Eric Fagan 	case Ptr:
1298f083f689SJohn Baldwin 		fprintf(fp, "0x%lx", args[sc->offset]);
1299bbeaf6c0SSean Eric Fagan 		break;
1300d8984f48SDag-Erling Smørgrav 	case Readlinkres: {
13012bae4eb3SAlfred Perlstein 		char *tmp2;
13024e3da534SJohn Baldwin 
13032b75c8adSJohn Baldwin 		if (retval[0] == -1)
13042bae4eb3SAlfred Perlstein 			break;
13052b75c8adSJohn Baldwin 		tmp2 = get_string(pid, (void*)args[sc->offset], retval[0]);
1306f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
13072bae4eb3SAlfred Perlstein 		free(tmp2);
13082bae4eb3SAlfred Perlstein 		break;
1309d8984f48SDag-Erling Smørgrav 	}
1310d8984f48SDag-Erling Smørgrav 	case Ioctl: {
13114e3da534SJohn Baldwin 		const char *temp;
13124e3da534SJohn Baldwin 		unsigned long cmd;
13134e3da534SJohn Baldwin 
13144e3da534SJohn Baldwin 		cmd = args[sc->offset];
1315265e5898SJohn Baldwin 		temp = sysdecode_ioctlname(cmd);
131694355cfdSAndrey Zonov 		if (temp)
1317f083f689SJohn Baldwin 			fputs(temp, fp);
131894355cfdSAndrey Zonov 		else {
1319f083f689SJohn Baldwin 			fprintf(fp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
13204e3da534SJohn Baldwin 			    cmd, cmd & IOC_OUT ? "R" : "",
13214e3da534SJohn Baldwin 			    cmd & IOC_IN ? "W" : "", IOCGROUP(cmd),
13224e3da534SJohn Baldwin 			    isprint(IOCGROUP(cmd)) ? (char)IOCGROUP(cmd) : '?',
13234e3da534SJohn Baldwin 			    cmd & 0xFF, IOCPARM_LEN(cmd));
1324081e5c48SPav Lucistnik 		}
1325081e5c48SPav Lucistnik 		break;
1326d8984f48SDag-Erling Smørgrav 	}
1327d8984f48SDag-Erling Smørgrav 	case Timespec: {
1328e45a5a0dSDavid Malone 		struct timespec ts;
13294e3da534SJohn Baldwin 
133094355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &ts,
133194355cfdSAndrey Zonov 		    sizeof(ts)) != -1)
1332a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%09ld }", (intmax_t)ts.tv_sec,
133394355cfdSAndrey Zonov 			    ts.tv_nsec);
1334e45a5a0dSDavid Malone 		else
1335f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1336e45a5a0dSDavid Malone 		break;
1337d8984f48SDag-Erling Smørgrav 	}
13387d897327SJohn Baldwin 	case Timespec2: {
13397d897327SJohn Baldwin 		struct timespec ts[2];
13407d897327SJohn Baldwin 		const char *sep;
13417d897327SJohn Baldwin 		unsigned int i;
13427d897327SJohn Baldwin 
13437d897327SJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts))
13447d897327SJohn Baldwin 		    != -1) {
13451e2ec671SJohn Baldwin 			fputs("{ ", fp);
13467d897327SJohn Baldwin 			sep = "";
13477d897327SJohn Baldwin 			for (i = 0; i < nitems(ts); i++) {
13487d897327SJohn Baldwin 				fputs(sep, fp);
13497d897327SJohn Baldwin 				sep = ", ";
13507d897327SJohn Baldwin 				switch (ts[i].tv_nsec) {
13517d897327SJohn Baldwin 				case UTIME_NOW:
13527d897327SJohn Baldwin 					fprintf(fp, "UTIME_NOW");
13537d897327SJohn Baldwin 					break;
13547d897327SJohn Baldwin 				case UTIME_OMIT:
13557d897327SJohn Baldwin 					fprintf(fp, "UTIME_OMIT");
13567d897327SJohn Baldwin 					break;
13577d897327SJohn Baldwin 				default:
1358a1436773SJohn Baldwin 					fprintf(fp, "%jd.%09ld",
1359a1436773SJohn Baldwin 					    (intmax_t)ts[i].tv_sec,
1360a1436773SJohn Baldwin 					    ts[i].tv_nsec);
13617d897327SJohn Baldwin 					break;
13627d897327SJohn Baldwin 				}
13637d897327SJohn Baldwin 			}
13641e2ec671SJohn Baldwin 			fputs(" }", fp);
13657d897327SJohn Baldwin 		} else
1366f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
13677d897327SJohn Baldwin 		break;
13687d897327SJohn Baldwin 	}
1369d8984f48SDag-Erling Smørgrav 	case Timeval: {
1370e45a5a0dSDavid Malone 		struct timeval tv;
13714e3da534SJohn Baldwin 
137294355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
137394355cfdSAndrey Zonov 		    != -1)
1374a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld }", (intmax_t)tv.tv_sec,
137594355cfdSAndrey Zonov 			    tv.tv_usec);
1376081e5c48SPav Lucistnik 		else
1377f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1378081e5c48SPav Lucistnik 		break;
1379d8984f48SDag-Erling Smørgrav 	}
1380d8984f48SDag-Erling Smørgrav 	case Timeval2: {
1381081e5c48SPav Lucistnik 		struct timeval tv[2];
13824e3da534SJohn Baldwin 
138394355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
138494355cfdSAndrey Zonov 		    != -1)
1385a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1386a1436773SJohn Baldwin 			    (intmax_t)tv[0].tv_sec, tv[0].tv_usec,
1387a1436773SJohn Baldwin 			    (intmax_t)tv[1].tv_sec, tv[1].tv_usec);
1388e45a5a0dSDavid Malone 		else
1389f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1390e45a5a0dSDavid Malone 		break;
1391d8984f48SDag-Erling Smørgrav 	}
1392d8984f48SDag-Erling Smørgrav 	case Itimerval: {
1393e45a5a0dSDavid Malone 		struct itimerval itv;
13944e3da534SJohn Baldwin 
139594355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &itv,
139694355cfdSAndrey Zonov 		    sizeof(itv)) != -1)
1397a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1398a1436773SJohn Baldwin 			    (intmax_t)itv.it_interval.tv_sec,
1399081e5c48SPav Lucistnik 			    itv.it_interval.tv_usec,
1400a1436773SJohn Baldwin 			    (intmax_t)itv.it_value.tv_sec,
1401081e5c48SPav Lucistnik 			    itv.it_value.tv_usec);
1402e45a5a0dSDavid Malone 		else
1403f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1404e45a5a0dSDavid Malone 		break;
1405d8984f48SDag-Erling Smørgrav 	}
14061c99a22aSSteven Hartland 	case LinuxSockArgs:
14071c99a22aSSteven Hartland 	{
14081c99a22aSSteven Hartland 		struct linux_socketcall_args largs;
14094e3da534SJohn Baldwin 
14101c99a22aSSteven Hartland 		if (get_struct(pid, (void *)args[sc->offset], (void *)&largs,
1411fb7eabb0SJohn Baldwin 		    sizeof(largs)) != -1)
1412f083f689SJohn Baldwin 			fprintf(fp, "{ %s, 0x%lx }",
1413fb7eabb0SJohn Baldwin 			    lookup(linux_socketcall_ops, largs.what, 10),
14140a46af44SJohn Baldwin 			    (long unsigned int)largs.args);
1415fb7eabb0SJohn Baldwin 		else
1416f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
14171c99a22aSSteven Hartland 		break;
14181c99a22aSSteven Hartland 	}
1419d8984f48SDag-Erling Smørgrav 	case Pollfd: {
1420e45a5a0dSDavid Malone 		/*
142194355cfdSAndrey Zonov 		 * XXX: A Pollfd argument expects the /next/ syscall argument
142294355cfdSAndrey Zonov 		 * to be the number of fds in the array. This matches the poll
142394355cfdSAndrey Zonov 		 * syscall.
1424e45a5a0dSDavid Malone 		 */
1425e45a5a0dSDavid Malone 		struct pollfd *pfd;
1426e45a5a0dSDavid Malone 		int numfds = args[sc->offset + 1];
1427f083f689SJohn Baldwin 		size_t bytes = sizeof(struct pollfd) * numfds;
1428f083f689SJohn Baldwin 		int i;
1429e45a5a0dSDavid Malone 
1430e45a5a0dSDavid Malone 		if ((pfd = malloc(bytes)) == NULL)
1431f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for pollfd array",
143294355cfdSAndrey Zonov 			    bytes);
143394355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], pfd, bytes)
143494355cfdSAndrey Zonov 		    != -1) {
1435f083f689SJohn Baldwin 			fputs("{", fp);
1436e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1437f083f689SJohn Baldwin 				fprintf(fp, " %d/%s", pfd[i].fd,
1438081e5c48SPav Lucistnik 				    xlookup_bits(poll_flags, pfd[i].events));
1439e45a5a0dSDavid Malone 			}
1440f083f689SJohn Baldwin 			fputs(" }", fp);
1441d8984f48SDag-Erling Smørgrav 		} else {
1442f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1443e45a5a0dSDavid Malone 		}
1444d8984f48SDag-Erling Smørgrav 		free(pfd);
1445e45a5a0dSDavid Malone 		break;
1446d8984f48SDag-Erling Smørgrav 	}
1447d8984f48SDag-Erling Smørgrav 	case Fd_set: {
1448e45a5a0dSDavid Malone 		/*
144994355cfdSAndrey Zonov 		 * XXX: A Fd_set argument expects the /first/ syscall argument
145094355cfdSAndrey Zonov 		 * to be the number of fds in the array.  This matches the
145194355cfdSAndrey Zonov 		 * select syscall.
1452e45a5a0dSDavid Malone 		 */
1453e45a5a0dSDavid Malone 		fd_set *fds;
1454e45a5a0dSDavid Malone 		int numfds = args[0];
1455f083f689SJohn Baldwin 		size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
1456f083f689SJohn Baldwin 		int i;
1457e45a5a0dSDavid Malone 
1458e45a5a0dSDavid Malone 		if ((fds = malloc(bytes)) == NULL)
1459f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for fd_set array",
146094355cfdSAndrey Zonov 			    bytes);
146194355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], fds, bytes)
146294355cfdSAndrey Zonov 		    != -1) {
1463f083f689SJohn Baldwin 			fputs("{", fp);
1464e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1465f083f689SJohn Baldwin 				if (FD_ISSET(i, fds))
1466f083f689SJohn Baldwin 					fprintf(fp, " %d", i);
1467e45a5a0dSDavid Malone 			}
1468f083f689SJohn Baldwin 			fputs(" }", fp);
146994355cfdSAndrey Zonov 		} else
1470f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1471d8984f48SDag-Erling Smørgrav 		free(fds);
1472e45a5a0dSDavid Malone 		break;
1473d8984f48SDag-Erling Smørgrav 	}
147434763d1cSJohn Baldwin 	case Signal:
1475f083f689SJohn Baldwin 		fputs(strsig2(args[sc->offset]), fp);
1476f0ebbc29SDag-Erling Smørgrav 		break;
1477d8984f48SDag-Erling Smørgrav 	case Sigset: {
1478081e5c48SPav Lucistnik 		long sig;
1479081e5c48SPav Lucistnik 		sigset_t ss;
1480f083f689SJohn Baldwin 		int i, first;
1481081e5c48SPav Lucistnik 
1482081e5c48SPav Lucistnik 		sig = args[sc->offset];
148394355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
148494355cfdSAndrey Zonov 		    sizeof(ss)) == -1) {
1485f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1486081e5c48SPav Lucistnik 			break;
1487081e5c48SPav Lucistnik 		}
1488f083f689SJohn Baldwin 		fputs("{ ", fp);
1489f083f689SJohn Baldwin 		first = 1;
1490d8984f48SDag-Erling Smørgrav 		for (i = 1; i < sys_nsig; i++) {
149134763d1cSJohn Baldwin 			if (sigismember(&ss, i)) {
1492f083f689SJohn Baldwin 				fprintf(fp, "%s%s", !first ? "|" : "",
14939289f547SJohn Baldwin 				    strsig2(i));
1494f083f689SJohn Baldwin 				first = 0;
149534763d1cSJohn Baldwin 			}
1496081e5c48SPav Lucistnik 		}
1497f083f689SJohn Baldwin 		if (!first)
1498f083f689SJohn Baldwin 			fputc(' ', fp);
1499f083f689SJohn Baldwin 		fputc('}', fp);
1500081e5c48SPav Lucistnik 		break;
1501d8984f48SDag-Erling Smørgrav 	}
15029289f547SJohn Baldwin 	case Sigprocmask:
15039289f547SJohn Baldwin 		print_integer_arg(sysdecode_sigprocmask_how, fp,
15049289f547SJohn Baldwin 		    args[sc->offset]);
1505894b8f7aSAlfred Perlstein 		break;
15069289f547SJohn Baldwin 	case Fcntlflag:
15074e3da534SJohn Baldwin 		/* XXX: Output depends on the value of the previous argument. */
15089289f547SJohn Baldwin 		if (sysdecode_fcntl_arg_p(args[sc->offset - 1]))
15099289f547SJohn Baldwin 			sysdecode_fcntl_arg(fp, args[sc->offset - 1],
15109289f547SJohn Baldwin 			    args[sc->offset], 16);
1511081e5c48SPav Lucistnik 		break;
1512081e5c48SPav Lucistnik 	case Open:
15139289f547SJohn Baldwin 		print_mask_arg(sysdecode_open_flags, fp, args[sc->offset]);
1514081e5c48SPav Lucistnik 		break;
1515081e5c48SPav Lucistnik 	case Fcntl:
15169289f547SJohn Baldwin 		print_integer_arg(sysdecode_fcntl_cmd, fp, args[sc->offset]);
1517081e5c48SPav Lucistnik 		break;
1518894b8f7aSAlfred Perlstein 	case Mprot:
15199289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_prot, fp, args[sc->offset]);
1520894b8f7aSAlfred Perlstein 		break;
15219289f547SJohn Baldwin 	case Mmapflags:
15229289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_flags, fp, args[sc->offset]);
1523894b8f7aSAlfred Perlstein 		break;
1524fde3a7d1SAlfred Perlstein 	case Whence:
15259289f547SJohn Baldwin 		print_integer_arg(sysdecode_whence, fp, args[sc->offset]);
1526081e5c48SPav Lucistnik 		break;
1527081e5c48SPav Lucistnik 	case Sockdomain:
15289289f547SJohn Baldwin 		print_integer_arg(sysdecode_socketdomain, fp, args[sc->offset]);
1529081e5c48SPav Lucistnik 		break;
15309289f547SJohn Baldwin 	case Socktype:
15319289f547SJohn Baldwin 		print_mask_arg(sysdecode_socket_type, fp, args[sc->offset]);
1532081e5c48SPav Lucistnik 		break;
1533081e5c48SPav Lucistnik 	case Shutdown:
15349289f547SJohn Baldwin 		print_integer_arg(sysdecode_shutdown_how, fp, args[sc->offset]);
1535081e5c48SPav Lucistnik 		break;
1536081e5c48SPav Lucistnik 	case Resource:
15379289f547SJohn Baldwin 		print_integer_arg(sysdecode_rlimit, fp, args[sc->offset]);
1538081e5c48SPav Lucistnik 		break;
1539081e5c48SPav Lucistnik 	case Pathconf:
1540f083f689SJohn Baldwin 		fputs(xlookup(pathconf_arg, args[sc->offset]), fp);
1541fde3a7d1SAlfred Perlstein 		break;
15429e1db66eSMark Johnston 	case Rforkflags:
15439289f547SJohn Baldwin 		print_mask_arg(sysdecode_rfork_flags, fp, args[sc->offset]);
15449e1db66eSMark Johnston 		break;
1545d8984f48SDag-Erling Smørgrav 	case Sockaddr: {
15469ddd1412SDag-Erling Smørgrav 		char addr[64];
15471be5d704SMark Murray 		struct sockaddr_in *lsin;
15481be5d704SMark Murray 		struct sockaddr_in6 *lsin6;
1549dec17687SBrian Feldman 		struct sockaddr_un *sun;
1550dec17687SBrian Feldman 		struct sockaddr *sa;
155166917ca9SJohn Baldwin 		socklen_t len;
1552dec17687SBrian Feldman 		u_char *q;
15539ddd1412SDag-Erling Smørgrav 
1554a7a08c7eSMarcel Moolenaar 		if (args[sc->offset] == 0) {
1555f083f689SJohn Baldwin 			fputs("NULL", fp);
1556a7a08c7eSMarcel Moolenaar 			break;
1557a7a08c7eSMarcel Moolenaar 		}
1558a7a08c7eSMarcel Moolenaar 
15596a656761SAlfred Perlstein 		/*
156066917ca9SJohn Baldwin 		 * Extract the address length from the next argument.  If
156166917ca9SJohn Baldwin 		 * this is an output sockaddr (OUT is set), then the
156266917ca9SJohn Baldwin 		 * next argument is a pointer to a socklen_t.  Otherwise
156366917ca9SJohn Baldwin 		 * the next argument contains a socklen_t by value.
15646a656761SAlfred Perlstein 		 */
156566917ca9SJohn Baldwin 		if (sc->type & OUT) {
156666917ca9SJohn Baldwin 			if (get_struct(pid, (void *)args[sc->offset + 1],
156766917ca9SJohn Baldwin 			    &len, sizeof(len)) == -1) {
156866917ca9SJohn Baldwin 				fprintf(fp, "0x%lx", args[sc->offset]);
15696a656761SAlfred Perlstein 				break;
15706a656761SAlfred Perlstein 			}
157166917ca9SJohn Baldwin 		} else
157266917ca9SJohn Baldwin 			len = args[sc->offset + 1];
157366917ca9SJohn Baldwin 
157466917ca9SJohn Baldwin 		/* If the length is too small, just bail. */
157566917ca9SJohn Baldwin 		if (len < sizeof(*sa)) {
1576f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1577f083f689SJohn Baldwin 			break;
15789ddd1412SDag-Erling Smørgrav 		}
1579dec17687SBrian Feldman 
158066917ca9SJohn Baldwin 		sa = calloc(1, len);
158166917ca9SJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], sa, len) == -1) {
158266917ca9SJohn Baldwin 			free(sa);
158366917ca9SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
158466917ca9SJohn Baldwin 			break;
158566917ca9SJohn Baldwin 		}
158666917ca9SJohn Baldwin 
158766917ca9SJohn Baldwin 		switch (sa->sa_family) {
1588dec17687SBrian Feldman 		case AF_INET:
158966917ca9SJohn Baldwin 			if (len < sizeof(*lsin))
159066917ca9SJohn Baldwin 				goto sockaddr_short;
159166917ca9SJohn Baldwin 			lsin = (struct sockaddr_in *)(void *)sa;
15924e3da534SJohn Baldwin 			inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr));
1593f083f689SJohn Baldwin 			fprintf(fp, "{ AF_INET %s:%d }", addr,
159494355cfdSAndrey Zonov 			    htons(lsin->sin_port));
1595dec17687SBrian Feldman 			break;
1596dec17687SBrian Feldman 		case AF_INET6:
159766917ca9SJohn Baldwin 			if (len < sizeof(*lsin6))
159866917ca9SJohn Baldwin 				goto sockaddr_short;
159966917ca9SJohn Baldwin 			lsin6 = (struct sockaddr_in6 *)(void *)sa;
160094355cfdSAndrey Zonov 			inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
16014e3da534SJohn Baldwin 			    sizeof(addr));
1602f083f689SJohn Baldwin 			fprintf(fp, "{ AF_INET6 [%s]:%d }", addr,
160394355cfdSAndrey Zonov 			    htons(lsin6->sin6_port));
1604dec17687SBrian Feldman 			break;
1605dec17687SBrian Feldman 		case AF_UNIX:
160666917ca9SJohn Baldwin 			sun = (struct sockaddr_un *)sa;
160766917ca9SJohn Baldwin 			fprintf(fp, "{ AF_UNIX \"%.*s\" }",
160866917ca9SJohn Baldwin 			    (int)(len - offsetof(struct sockaddr_un, sun_path)),
160966917ca9SJohn Baldwin 			    sun->sun_path);
1610dec17687SBrian Feldman 			break;
1611dec17687SBrian Feldman 		default:
161266917ca9SJohn Baldwin 		sockaddr_short:
1613f083f689SJohn Baldwin 			fprintf(fp,
1614f083f689SJohn Baldwin 			    "{ sa_len = %d, sa_family = %d, sa_data = {",
1615f083f689SJohn Baldwin 			    (int)sa->sa_len, (int)sa->sa_family);
1616f083f689SJohn Baldwin 			for (q = (u_char *)sa->sa_data;
161766917ca9SJohn Baldwin 			     q < (u_char *)sa + len; q++)
1618f083f689SJohn Baldwin 				fprintf(fp, "%s 0x%02x",
1619f083f689SJohn Baldwin 				    q == (u_char *)sa->sa_data ? "" : ",",
1620f083f689SJohn Baldwin 				    *q);
1621f083f689SJohn Baldwin 			fputs(" } }", fp);
1622dec17687SBrian Feldman 		}
162366917ca9SJohn Baldwin 		free(sa);
16249ddd1412SDag-Erling Smørgrav 		break;
1625d8984f48SDag-Erling Smørgrav 	}
1626d8984f48SDag-Erling Smørgrav 	case Sigaction: {
1627e45a5a0dSDavid Malone 		struct sigaction sa;
1628e45a5a0dSDavid Malone 
162994355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa))
163094355cfdSAndrey Zonov 		    != -1) {
1631f083f689SJohn Baldwin 			fputs("{ ", fp);
1632e45a5a0dSDavid Malone 			if (sa.sa_handler == SIG_DFL)
1633f083f689SJohn Baldwin 				fputs("SIG_DFL", fp);
1634e45a5a0dSDavid Malone 			else if (sa.sa_handler == SIG_IGN)
1635f083f689SJohn Baldwin 				fputs("SIG_IGN", fp);
1636e45a5a0dSDavid Malone 			else
1637f083f689SJohn Baldwin 				fprintf(fp, "%p", sa.sa_handler);
1638f083f689SJohn Baldwin 			fprintf(fp, " %s ss_t }",
1639081e5c48SPav Lucistnik 			    xlookup_bits(sigaction_flags, sa.sa_flags));
164094355cfdSAndrey Zonov 		} else
1641f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1642e45a5a0dSDavid Malone 		break;
1643d8984f48SDag-Erling Smørgrav 	}
1644d8984f48SDag-Erling Smørgrav 	case Kevent: {
1645081e5c48SPav Lucistnik 		/*
16464e3da534SJohn Baldwin 		 * XXX XXX: The size of the array is determined by either the
1647081e5c48SPav Lucistnik 		 * next syscall argument, or by the syscall return value,
1648081e5c48SPav Lucistnik 		 * depending on which argument number we are.  This matches the
1649081e5c48SPav Lucistnik 		 * kevent syscall, but luckily that's the only syscall that uses
1650081e5c48SPav Lucistnik 		 * them.
1651081e5c48SPav Lucistnik 		 */
1652081e5c48SPav Lucistnik 		struct kevent *ke;
1653081e5c48SPav Lucistnik 		int numevents = -1;
1654f083f689SJohn Baldwin 		size_t bytes;
1655f083f689SJohn Baldwin 		int i;
1656081e5c48SPav Lucistnik 
1657081e5c48SPav Lucistnik 		if (sc->offset == 1)
1658081e5c48SPav Lucistnik 			numevents = args[sc->offset+1];
16592b75c8adSJohn Baldwin 		else if (sc->offset == 3 && retval[0] != -1)
16602b75c8adSJohn Baldwin 			numevents = retval[0];
1661081e5c48SPav Lucistnik 
1662f083f689SJohn Baldwin 		if (numevents >= 0) {
1663081e5c48SPav Lucistnik 			bytes = sizeof(struct kevent) * numevents;
1664081e5c48SPav Lucistnik 			if ((ke = malloc(bytes)) == NULL)
1665f083f689SJohn Baldwin 				err(1,
1666f083f689SJohn Baldwin 				    "Cannot malloc %zu bytes for kevent array",
166794355cfdSAndrey Zonov 				    bytes);
1668f083f689SJohn Baldwin 		} else
1669f083f689SJohn Baldwin 			ke = NULL;
167094355cfdSAndrey Zonov 		if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset],
167194355cfdSAndrey Zonov 		    ke, bytes) != -1) {
1672f083f689SJohn Baldwin 			fputc('{', fp);
1673c915ff03SJohn Baldwin 			for (i = 0; i < numevents; i++) {
1674c915ff03SJohn Baldwin 				fputc(' ', fp);
1675c915ff03SJohn Baldwin 				print_kevent(fp, &ke[i], sc->offset == 1);
1676c915ff03SJohn Baldwin 			}
1677f083f689SJohn Baldwin 			fputs(" }", fp);
1678d8984f48SDag-Erling Smørgrav 		} else {
1679f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1680081e5c48SPav Lucistnik 		}
1681d8984f48SDag-Erling Smørgrav 		free(ke);
1682081e5c48SPav Lucistnik 		break;
1683d8984f48SDag-Erling Smørgrav 	}
1684d8984f48SDag-Erling Smørgrav 	case Stat: {
1685081e5c48SPav Lucistnik 		struct stat st;
16864e3da534SJohn Baldwin 
168794355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st))
168894355cfdSAndrey Zonov 		    != -1) {
1689081e5c48SPav Lucistnik 			char mode[12];
16904e3da534SJohn Baldwin 
1691081e5c48SPav Lucistnik 			strmode(st.st_mode, mode);
1692f083f689SJohn Baldwin 			fprintf(fp,
1693b38fbc2eSJohn Baldwin 			    "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode,
1694b38fbc2eSJohn Baldwin 			    (uintmax_t)st.st_ino, (intmax_t)st.st_size,
169594355cfdSAndrey Zonov 			    (long)st.st_blksize);
1696d8984f48SDag-Erling Smørgrav 		} else {
1697f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1698081e5c48SPav Lucistnik 		}
1699081e5c48SPav Lucistnik 		break;
1700d8984f48SDag-Erling Smørgrav 	}
1701a776866bSBryan Drewery 	case StatFs: {
1702a776866bSBryan Drewery 		unsigned int i;
1703a776866bSBryan Drewery 		struct statfs buf;
17040a71c082SBryan Drewery 
1705a776866bSBryan Drewery 		if (get_struct(pid, (void *)args[sc->offset], &buf,
1706a776866bSBryan Drewery 		    sizeof(buf)) != -1) {
1707a776866bSBryan Drewery 			char fsid[17];
1708a776866bSBryan Drewery 
1709a776866bSBryan Drewery 			bzero(fsid, sizeof(fsid));
1710a776866bSBryan Drewery 			if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) {
1711a776866bSBryan Drewery 			        for (i = 0; i < sizeof(buf.f_fsid); i++)
1712a776866bSBryan Drewery 					snprintf(&fsid[i*2],
1713a776866bSBryan Drewery 					    sizeof(fsid) - (i*2), "%02x",
1714a776866bSBryan Drewery 					    ((u_char *)&buf.f_fsid)[i]);
1715a776866bSBryan Drewery 			}
1716a776866bSBryan Drewery 			fprintf(fp,
1717a776866bSBryan Drewery 			    "{ fstypename=%s,mntonname=%s,mntfromname=%s,"
1718a776866bSBryan Drewery 			    "fsid=%s }", buf.f_fstypename, buf.f_mntonname,
1719a776866bSBryan Drewery 			    buf.f_mntfromname, fsid);
1720a776866bSBryan Drewery 		} else
1721a776866bSBryan Drewery 			fprintf(fp, "0x%lx", args[sc->offset]);
1722a776866bSBryan Drewery 		break;
1723a776866bSBryan Drewery 	}
1724a776866bSBryan Drewery 
1725d8984f48SDag-Erling Smørgrav 	case Rusage: {
1726081e5c48SPav Lucistnik 		struct rusage ru;
17274e3da534SJohn Baldwin 
172894355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru))
172994355cfdSAndrey Zonov 		    != -1) {
1730f083f689SJohn Baldwin 			fprintf(fp,
1731a1436773SJohn Baldwin 			    "{ u=%jd.%06ld,s=%jd.%06ld,in=%ld,out=%ld }",
1732a1436773SJohn Baldwin 			    (intmax_t)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
1733a1436773SJohn Baldwin 			    (intmax_t)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
1734081e5c48SPav Lucistnik 			    ru.ru_inblock, ru.ru_oublock);
173594355cfdSAndrey Zonov 		} else
1736f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1737081e5c48SPav Lucistnik 		break;
1738d8984f48SDag-Erling Smørgrav 	}
1739d8984f48SDag-Erling Smørgrav 	case Rlimit: {
1740081e5c48SPav Lucistnik 		struct rlimit rl;
17414e3da534SJohn Baldwin 
174294355cfdSAndrey Zonov 		if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl))
174394355cfdSAndrey Zonov 		    != -1) {
1744f083f689SJohn Baldwin 			fprintf(fp, "{ cur=%ju,max=%ju }",
1745081e5c48SPav Lucistnik 			    rl.rlim_cur, rl.rlim_max);
174694355cfdSAndrey Zonov 		} else
1747f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
1748081e5c48SPav Lucistnik 		break;
1749d8984f48SDag-Erling Smørgrav 	}
175034763d1cSJohn Baldwin 	case ExitStatus: {
175134763d1cSJohn Baldwin 		int status;
1752f083f689SJohn Baldwin 
175334763d1cSJohn Baldwin 		if (get_struct(pid, (void *)args[sc->offset], &status,
175434763d1cSJohn Baldwin 		    sizeof(status)) != -1) {
1755f083f689SJohn Baldwin 			fputs("{ ", fp);
175634763d1cSJohn Baldwin 			if (WIFCONTINUED(status))
1757f083f689SJohn Baldwin 				fputs("CONTINUED", fp);
175834763d1cSJohn Baldwin 			else if (WIFEXITED(status))
1759f083f689SJohn Baldwin 				fprintf(fp, "EXITED,val=%d",
176034763d1cSJohn Baldwin 				    WEXITSTATUS(status));
176134763d1cSJohn Baldwin 			else if (WIFSIGNALED(status))
1762f083f689SJohn Baldwin 				fprintf(fp, "SIGNALED,sig=%s%s",
1763f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)),
176434763d1cSJohn Baldwin 				    WCOREDUMP(status) ? ",cored" : "");
176534763d1cSJohn Baldwin 			else
1766f083f689SJohn Baldwin 				fprintf(fp, "STOPPED,sig=%s",
1767f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)));
1768f083f689SJohn Baldwin 			fputs(" }", fp);
176934763d1cSJohn Baldwin 		} else
1770f083f689SJohn Baldwin 			fprintf(fp, "0x%lx", args[sc->offset]);
177134763d1cSJohn Baldwin 		break;
177234763d1cSJohn Baldwin 	}
177334763d1cSJohn Baldwin 	case Waitoptions:
17749289f547SJohn Baldwin 		print_mask_arg(sysdecode_wait6_options, fp, args[sc->offset]);
177534763d1cSJohn Baldwin 		break;
177634763d1cSJohn Baldwin 	case Idtype:
17779289f547SJohn Baldwin 		print_integer_arg(sysdecode_idtype, fp, args[sc->offset]);
177834763d1cSJohn Baldwin 		break;
177955648840SJohn Baldwin 	case Procctl:
17809289f547SJohn Baldwin 		print_integer_arg(sysdecode_procctl_cmd, fp, args[sc->offset]);
178155648840SJohn Baldwin 		break;
1782fdb5bf37SJohn Baldwin 	case Umtxop:
17839289f547SJohn Baldwin 		print_integer_arg(sysdecode_umtx_op, fp, args[sc->offset]);
1784fdb5bf37SJohn Baldwin 		break;
17857d897327SJohn Baldwin 	case Atfd:
17869289f547SJohn Baldwin 		print_integer_arg(sysdecode_atfd, fp, args[sc->offset]);
17877d897327SJohn Baldwin 		break;
17887d897327SJohn Baldwin 	case Atflags:
1789f083f689SJohn Baldwin 		fputs(xlookup_bits(at_flags, args[sc->offset]), fp);
17907d897327SJohn Baldwin 		break;
17917d897327SJohn Baldwin 	case Accessmode:
17929289f547SJohn Baldwin 		print_mask_arg(sysdecode_access_mode, fp, args[sc->offset]);
17937d897327SJohn Baldwin 		break;
1794b289a8d7SJohn Baldwin 	case Sysarch:
1795f083f689SJohn Baldwin 		fputs(xlookup(sysarch_ops, args[sc->offset]), fp);
1796b289a8d7SJohn Baldwin 		break;
17972b75c8adSJohn Baldwin 	case PipeFds:
17982b75c8adSJohn Baldwin 		/*
17992b75c8adSJohn Baldwin 		 * The pipe() system call in the kernel returns its
18002b75c8adSJohn Baldwin 		 * two file descriptors via return values.  However,
18012b75c8adSJohn Baldwin 		 * the interface exposed by libc is that pipe()
18022b75c8adSJohn Baldwin 		 * accepts a pointer to an array of descriptors.
18032b75c8adSJohn Baldwin 		 * Format the output to match the libc API by printing
18042b75c8adSJohn Baldwin 		 * the returned file descriptors as a fake argument.
18052b75c8adSJohn Baldwin 		 *
18062b75c8adSJohn Baldwin 		 * Overwrite the first retval to signal a successful
18072b75c8adSJohn Baldwin 		 * return as well.
18082b75c8adSJohn Baldwin 		 */
18092b75c8adSJohn Baldwin 		fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]);
18102b75c8adSJohn Baldwin 		retval[0] = 0;
18112b75c8adSJohn Baldwin 		break;
1812195aef99SBryan Drewery 	case Utrace: {
1813195aef99SBryan Drewery 		size_t len;
1814195aef99SBryan Drewery 		void *utrace_addr;
1815195aef99SBryan Drewery 
1816195aef99SBryan Drewery 		len = args[sc->offset + 1];
1817195aef99SBryan Drewery 		utrace_addr = calloc(1, len);
1818195aef99SBryan Drewery 		if (get_struct(pid, (void *)args[sc->offset],
1819195aef99SBryan Drewery 		    (void *)utrace_addr, len) != -1)
1820195aef99SBryan Drewery 			print_utrace(fp, utrace_addr, len);
1821195aef99SBryan Drewery 		else
1822195aef99SBryan Drewery 			fprintf(fp, "0x%lx", args[sc->offset]);
1823195aef99SBryan Drewery 		free(utrace_addr);
1824195aef99SBryan Drewery 		break;
1825195aef99SBryan Drewery 	}
1826808d9805SEd Schouten 	case IntArray: {
1827808d9805SEd Schouten 		int descriptors[16];
1828808d9805SEd Schouten 		unsigned long i, ndescriptors;
1829808d9805SEd Schouten 		bool truncated;
1830808d9805SEd Schouten 
1831808d9805SEd Schouten 		ndescriptors = args[sc->offset + 1];
1832808d9805SEd Schouten 		truncated = false;
1833808d9805SEd Schouten 		if (ndescriptors > nitems(descriptors)) {
1834808d9805SEd Schouten 			ndescriptors = nitems(descriptors);
1835808d9805SEd Schouten 			truncated = true;
1836808d9805SEd Schouten 		}
1837808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset],
1838808d9805SEd Schouten 		    descriptors, ndescriptors * sizeof(descriptors[0])) != -1) {
1839808d9805SEd Schouten 			fprintf(fp, "{");
1840808d9805SEd Schouten 			for (i = 0; i < ndescriptors; i++)
1841808d9805SEd Schouten 				fprintf(fp, i == 0 ? " %d" : ", %d",
1842808d9805SEd Schouten 				    descriptors[i]);
1843808d9805SEd Schouten 			fprintf(fp, truncated ? ", ... }" : " }");
1844808d9805SEd Schouten 		} else
1845808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1846808d9805SEd Schouten 		break;
1847808d9805SEd Schouten 	}
18489289f547SJohn Baldwin 	case Pipe2:
18499289f547SJohn Baldwin 		print_mask_arg(sysdecode_pipe2_flags, fp, args[sc->offset]);
18509289f547SJohn Baldwin 		break;
1851*bed418c8SJohn Baldwin 	case CapFcntlRights: {
1852*bed418c8SJohn Baldwin 		uint32_t rights;
1853*bed418c8SJohn Baldwin 
1854*bed418c8SJohn Baldwin 		if (sc->type & OUT) {
1855*bed418c8SJohn Baldwin 			if (get_struct(pid, (void *)args[sc->offset], &rights,
1856*bed418c8SJohn Baldwin 			    sizeof(rights)) == -1) {
1857*bed418c8SJohn Baldwin 				fprintf(fp, "0x%lx", args[sc->offset]);
1858*bed418c8SJohn Baldwin 				break;
1859*bed418c8SJohn Baldwin 			}
1860*bed418c8SJohn Baldwin 		} else
1861*bed418c8SJohn Baldwin 			rights = args[sc->offset];
1862*bed418c8SJohn Baldwin 		print_mask_arg32(sysdecode_cap_fcntlrights, fp, rights);
1863*bed418c8SJohn Baldwin 		break;
1864*bed418c8SJohn Baldwin 	}
1865808d9805SEd Schouten 
1866808d9805SEd Schouten 	case CloudABIAdvice:
1867808d9805SEd Schouten 		fputs(xlookup(cloudabi_advice, args[sc->offset]), fp);
1868808d9805SEd Schouten 		break;
1869808d9805SEd Schouten 	case CloudABIClockID:
1870808d9805SEd Schouten 		fputs(xlookup(cloudabi_clockid, args[sc->offset]), fp);
1871808d9805SEd Schouten 		break;
1872808d9805SEd Schouten 	case ClouduABIFDSFlags:
1873808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_fdsflags, args[sc->offset]), fp);
1874808d9805SEd Schouten 		break;
1875808d9805SEd Schouten 	case CloudABIFDStat: {
1876808d9805SEd Schouten 		cloudabi_fdstat_t fds;
1877808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &fds, sizeof(fds))
1878808d9805SEd Schouten 		    != -1) {
1879808d9805SEd Schouten 			fprintf(fp, "{ %s, ",
1880808d9805SEd Schouten 			    xlookup(cloudabi_filetype, fds.fs_filetype));
1881808d9805SEd Schouten 			fprintf(fp, "%s, ... }",
1882808d9805SEd Schouten 			    xlookup_bits(cloudabi_fdflags, fds.fs_flags));
1883808d9805SEd Schouten 		} else
1884808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1885808d9805SEd Schouten 		break;
1886808d9805SEd Schouten 	}
1887808d9805SEd Schouten 	case CloudABIFileStat: {
1888808d9805SEd Schouten 		cloudabi_filestat_t fsb;
1889808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &fsb, sizeof(fsb))
1890808d9805SEd Schouten 		    != -1)
18919ba32307SJohn Baldwin 			fprintf(fp, "{ %s, %ju }",
1892808d9805SEd Schouten 			    xlookup(cloudabi_filetype, fsb.st_filetype),
18939ba32307SJohn Baldwin 			    (uintmax_t)fsb.st_size);
1894808d9805SEd Schouten 		else
1895808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1896808d9805SEd Schouten 		break;
1897808d9805SEd Schouten 	}
1898808d9805SEd Schouten 	case CloudABIFileType:
1899808d9805SEd Schouten 		fputs(xlookup(cloudabi_filetype, args[sc->offset]), fp);
1900808d9805SEd Schouten 		break;
1901808d9805SEd Schouten 	case CloudABIFSFlags:
1902808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_fsflags, args[sc->offset]), fp);
1903808d9805SEd Schouten 		break;
1904808d9805SEd Schouten 	case CloudABILookup:
1905808d9805SEd Schouten 		if ((args[sc->offset] & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) != 0)
1906808d9805SEd Schouten 			fprintf(fp, "%d|LOOKUP_SYMLINK_FOLLOW",
1907808d9805SEd Schouten 			    (int)args[sc->offset]);
1908808d9805SEd Schouten 		else
1909808d9805SEd Schouten 			fprintf(fp, "%d", (int)args[sc->offset]);
1910808d9805SEd Schouten 		break;
1911808d9805SEd Schouten 	case CloudABIMFlags:
1912808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_mflags, args[sc->offset]), fp);
1913808d9805SEd Schouten 		break;
1914808d9805SEd Schouten 	case CloudABIMProt:
1915808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_mprot, args[sc->offset]), fp);
1916808d9805SEd Schouten 		break;
1917808d9805SEd Schouten 	case CloudABIMSFlags:
1918808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_msflags, args[sc->offset]), fp);
1919808d9805SEd Schouten 		break;
1920808d9805SEd Schouten 	case CloudABIOFlags:
1921808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_oflags, args[sc->offset]), fp);
1922808d9805SEd Schouten 		break;
1923808d9805SEd Schouten 	case CloudABISDFlags:
1924808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_sdflags, args[sc->offset]), fp);
1925808d9805SEd Schouten 		break;
1926808d9805SEd Schouten 	case CloudABISignal:
1927808d9805SEd Schouten 		fputs(xlookup(cloudabi_signal, args[sc->offset]), fp);
1928808d9805SEd Schouten 		break;
1929808d9805SEd Schouten 	case CloudABISockStat: {
1930808d9805SEd Schouten 		cloudabi_sockstat_t ss;
1931808d9805SEd Schouten 		if (get_struct(pid, (void *)args[sc->offset], &ss, sizeof(ss))
1932808d9805SEd Schouten 		    != -1) {
1933808d9805SEd Schouten 			fprintf(fp, "{ %s, ", xlookup(
1934808d9805SEd Schouten 			    cloudabi_sa_family, ss.ss_sockname.sa_family));
1935808d9805SEd Schouten 			fprintf(fp, "%s, ", xlookup(
1936808d9805SEd Schouten 			    cloudabi_sa_family, ss.ss_peername.sa_family));
1937808d9805SEd Schouten 			fprintf(fp, "%s, ", xlookup(
1938808d9805SEd Schouten 			    cloudabi_errno, ss.ss_error));
1939808d9805SEd Schouten 			fprintf(fp, "%s }", xlookup_bits(
1940808d9805SEd Schouten 			    cloudabi_ssstate, ss.ss_state));
1941808d9805SEd Schouten 		} else
1942808d9805SEd Schouten 			fprintf(fp, "0x%lx", args[sc->offset]);
1943808d9805SEd Schouten 		break;
1944808d9805SEd Schouten 	}
1945808d9805SEd Schouten 	case CloudABISSFlags:
1946808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_ssflags, args[sc->offset]), fp);
1947808d9805SEd Schouten 		break;
1948808d9805SEd Schouten 	case CloudABITimestamp:
1949808d9805SEd Schouten 		fprintf(fp, "%lu.%09lus", args[sc->offset] / 1000000000,
1950808d9805SEd Schouten 		    args[sc->offset] % 1000000000);
1951808d9805SEd Schouten 		break;
1952808d9805SEd Schouten 	case CloudABIULFlags:
1953808d9805SEd Schouten 		fputs(xlookup_bits(cloudabi_ulflags, args[sc->offset]), fp);
1954808d9805SEd Schouten 		break;
1955808d9805SEd Schouten 	case CloudABIWhence:
1956808d9805SEd Schouten 		fputs(xlookup(cloudabi_whence, args[sc->offset]), fp);
1957808d9805SEd Schouten 		break;
1958808d9805SEd Schouten 
1959081e5c48SPav Lucistnik 	default:
1960081e5c48SPav Lucistnik 		errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
1961bbeaf6c0SSean Eric Fagan 	}
1962f083f689SJohn Baldwin 	fclose(fp);
1963d8984f48SDag-Erling Smørgrav 	return (tmp);
1964bbeaf6c0SSean Eric Fagan }
1965bbeaf6c0SSean Eric Fagan 
1966bbeaf6c0SSean Eric Fagan /*
196700ddbdf2SJohn Baldwin  * Print (to outfile) the system call and its arguments.
1968bbeaf6c0SSean Eric Fagan  */
1969bbeaf6c0SSean Eric Fagan void
197000ddbdf2SJohn Baldwin print_syscall(struct trussinfo *trussinfo)
1971d8984f48SDag-Erling Smørgrav {
197200ddbdf2SJohn Baldwin 	struct threadinfo *t;
197300ddbdf2SJohn Baldwin 	const char *name;
197400ddbdf2SJohn Baldwin 	char **s_args;
197500ddbdf2SJohn Baldwin 	int i, len, nargs;
19760d0bd00eSMatthew N. Dodd 
197700ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
1978c03bfcc8SMatthew N. Dodd 
19791175b23fSJohn Baldwin 	name = t->cs.sc->name;
198000ddbdf2SJohn Baldwin 	nargs = t->cs.nargs;
198100ddbdf2SJohn Baldwin 	s_args = t->cs.s_args;
19820d0bd00eSMatthew N. Dodd 
1983d70876fdSJohn Baldwin 	len = print_line_prefix(trussinfo);
1984ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, "%s(", name);
1985c03bfcc8SMatthew N. Dodd 
1986bbeaf6c0SSean Eric Fagan 	for (i = 0; i < nargs; i++) {
198700ddbdf2SJohn Baldwin 		if (s_args[i] != NULL)
1988ec0bed25SMatthew N. Dodd 			len += fprintf(trussinfo->outfile, "%s", s_args[i]);
1989bbeaf6c0SSean Eric Fagan 		else
199094355cfdSAndrey Zonov 			len += fprintf(trussinfo->outfile,
199194355cfdSAndrey Zonov 			    "<missing argument>");
199294355cfdSAndrey Zonov 		len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ?
199394355cfdSAndrey Zonov 		    "," : "");
1994bbeaf6c0SSean Eric Fagan 	}
1995ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, ")");
19966cb533feSSean Eric Fagan 	for (i = 0; i < 6 - (len / 8); i++)
1997ec0bed25SMatthew N. Dodd 		fprintf(trussinfo->outfile, "\t");
19986cb533feSSean Eric Fagan }
19996cb533feSSean Eric Fagan 
20006cb533feSSean Eric Fagan void
200100ddbdf2SJohn Baldwin print_syscall_ret(struct trussinfo *trussinfo, int errorp, long *retval)
20021bcb5f5aSMarcel Moolenaar {
2003ee3b0f6eSDiomidis Spinellis 	struct timespec timediff;
200400ddbdf2SJohn Baldwin 	struct threadinfo *t;
200500ddbdf2SJohn Baldwin 	struct syscall *sc;
2006287b96ddSJohn Baldwin 	int error;
2007ee3b0f6eSDiomidis Spinellis 
200800ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
200900ddbdf2SJohn Baldwin 	sc = t->cs.sc;
2010ee3b0f6eSDiomidis Spinellis 	if (trussinfo->flags & COUNTONLY) {
201100ddbdf2SJohn Baldwin 		timespecsubt(&t->after, &t->before, &timediff);
2012d9dcc463SXin LI 		timespecadd(&sc->time, &timediff, &sc->time);
2013ee3b0f6eSDiomidis Spinellis 		sc->ncalls++;
2014ee3b0f6eSDiomidis Spinellis 		if (errorp)
2015ee3b0f6eSDiomidis Spinellis 			sc->nerror++;
2016ee3b0f6eSDiomidis Spinellis 		return;
2017ee3b0f6eSDiomidis Spinellis 	}
2018d8984f48SDag-Erling Smørgrav 
201900ddbdf2SJohn Baldwin 	print_syscall(trussinfo);
20200cf21b4fSBrian Somers 	fflush(trussinfo->outfile);
2021b9befd33SJohn Baldwin 
2022b9befd33SJohn Baldwin 	if (retval == NULL) {
2023b9befd33SJohn Baldwin 		/*
2024b9befd33SJohn Baldwin 		 * This system call resulted in the current thread's exit,
2025b9befd33SJohn Baldwin 		 * so there is no return value or error to display.
2026b9befd33SJohn Baldwin 		 */
2027b9befd33SJohn Baldwin 		fprintf(trussinfo->outfile, "\n");
2028b9befd33SJohn Baldwin 		return;
2029b9befd33SJohn Baldwin 	}
2030b9befd33SJohn Baldwin 
2031287b96ddSJohn Baldwin 	if (errorp) {
2032287b96ddSJohn Baldwin 		error = sysdecode_abi_to_freebsd_errno(t->proc->abi->abi,
2033287b96ddSJohn Baldwin 		    retval[0]);
20342b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0],
2035287b96ddSJohn Baldwin 		    error == INT_MAX ? "Unknown error" : strerror(error));
2036287b96ddSJohn Baldwin 	}
20372b75c8adSJohn Baldwin #ifndef __LP64__
20386c61b0f3SBryan Drewery 	else if (sc->ret_type == 2) {
20392b75c8adSJohn Baldwin 		off_t off;
20402b75c8adSJohn Baldwin 
20412b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
20422b75c8adSJohn Baldwin 		off = (off_t)retval[1] << 32 | retval[0];
20432b75c8adSJohn Baldwin #else
20442b75c8adSJohn Baldwin 		off = (off_t)retval[0] << 32 | retval[1];
20452b75c8adSJohn Baldwin #endif
20462b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " = %jd (0x%jx)\n", (intmax_t)off,
20472b75c8adSJohn Baldwin 		    (intmax_t)off);
20486cb533feSSean Eric Fagan 	}
20492b75c8adSJohn Baldwin #endif
20502b75c8adSJohn Baldwin 	else
20512b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval[0],
20522b75c8adSJohn Baldwin 		    retval[0]);
2053bbeaf6c0SSean Eric Fagan }
2054ee3b0f6eSDiomidis Spinellis 
2055ee3b0f6eSDiomidis Spinellis void
2056ee3b0f6eSDiomidis Spinellis print_summary(struct trussinfo *trussinfo)
2057ee3b0f6eSDiomidis Spinellis {
2058ee3b0f6eSDiomidis Spinellis 	struct timespec total = {0, 0};
205994355cfdSAndrey Zonov 	struct syscall *sc;
2060ee3b0f6eSDiomidis Spinellis 	int ncall, nerror;
2061ee3b0f6eSDiomidis Spinellis 
2062ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
2063ee3b0f6eSDiomidis Spinellis 	    "syscall", "seconds", "calls", "errors");
2064ee3b0f6eSDiomidis Spinellis 	ncall = nerror = 0;
20656c61b0f3SBryan Drewery 	STAILQ_FOREACH(sc, &syscalls, entries)
2066ee3b0f6eSDiomidis Spinellis 		if (sc->ncalls) {
206755a8d2bbSJaakko Heinonen 			fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
206855a8d2bbSJaakko Heinonen 			    sc->name, (intmax_t)sc->time.tv_sec,
206955a8d2bbSJaakko Heinonen 			    sc->time.tv_nsec, sc->ncalls, sc->nerror);
2070d9dcc463SXin LI 			timespecadd(&total, &sc->time, &total);
2071ee3b0f6eSDiomidis Spinellis 			ncall += sc->ncalls;
2072ee3b0f6eSDiomidis Spinellis 			nerror += sc->nerror;
2073ee3b0f6eSDiomidis Spinellis 		}
2074ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n",
2075ee3b0f6eSDiomidis Spinellis 	    "", "-------------", "-------", "-------");
207655a8d2bbSJaakko Heinonen 	fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
207755a8d2bbSJaakko Heinonen 	    "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror);
2078ee3b0f6eSDiomidis Spinellis }
2079