xref: /freebsd/usr.bin/truss/syscalls.c (revision b9b86b6742ad589e5ad1077c000bfdb2ce9ac198)
1df57947fSPedro F. Giffuni /*-
2df57947fSPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
3df57947fSPedro F. Giffuni  *
40a6c71f8SWarner Losh  * Copyright 1997 Sean Eric Fagan
509d64da3SSean Eric Fagan  *
609d64da3SSean Eric Fagan  * Redistribution and use in source and binary forms, with or without
709d64da3SSean Eric Fagan  * modification, are permitted provided that the following conditions
809d64da3SSean Eric Fagan  * are met:
909d64da3SSean Eric Fagan  * 1. Redistributions of source code must retain the above copyright
1009d64da3SSean Eric Fagan  *    notice, this list of conditions and the following disclaimer.
1109d64da3SSean Eric Fagan  * 2. Redistributions in binary form must reproduce the above copyright
1209d64da3SSean Eric Fagan  *    notice, this list of conditions and the following disclaimer in the
1309d64da3SSean Eric Fagan  *    documentation and/or other materials provided with the distribution.
1409d64da3SSean Eric Fagan  * 3. All advertising materials mentioning features or use of this software
1509d64da3SSean Eric Fagan  *    must display the following acknowledgement:
1609d64da3SSean Eric Fagan  *	This product includes software developed by Sean Eric Fagan
1709d64da3SSean Eric Fagan  * 4. Neither the name of the author may be used to endorse or promote
1809d64da3SSean Eric Fagan  *    products derived from this software without specific prior written
1909d64da3SSean Eric Fagan  *    permission.
2009d64da3SSean Eric Fagan  *
2109d64da3SSean Eric Fagan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2209d64da3SSean Eric Fagan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2309d64da3SSean Eric Fagan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2409d64da3SSean Eric Fagan  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2509d64da3SSean Eric Fagan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2609d64da3SSean Eric Fagan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2709d64da3SSean Eric Fagan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2809d64da3SSean Eric Fagan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2909d64da3SSean Eric Fagan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3009d64da3SSean Eric Fagan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3109d64da3SSean Eric Fagan  * SUCH DAMAGE.
3209d64da3SSean Eric Fagan  */
3309d64da3SSean Eric Fagan 
342b75c8adSJohn Baldwin #include <sys/cdefs.h>
352b75c8adSJohn Baldwin __FBSDID("$FreeBSD$");
363cf51049SPhilippe Charnier 
3709d64da3SSean Eric Fagan /*
38bbeaf6c0SSean Eric Fagan  * This file has routines used to print out system calls and their
39bbeaf6c0SSean Eric Fagan  * arguments.
40bbeaf6c0SSean Eric Fagan  */
41bbeaf6c0SSean Eric Fagan 
42bb24ee2bSThomas Munro #include <sys/aio.h>
437136a1d9SJohn Baldwin #include <sys/capsicum.h>
449ddd1412SDag-Erling Smørgrav #include <sys/types.h>
45ffb66079SJohn Baldwin #define	_WANT_FREEBSD11_KEVENT
462b75c8adSJohn Baldwin #include <sys/event.h>
472b75c8adSJohn Baldwin #include <sys/ioccom.h>
485b05dc5aSThomas Munro #include <sys/mman.h>
49a776866bSBryan Drewery #include <sys/mount.h>
506019514bSAlex Richardson #include <sys/poll.h>
5131dddc6aSAlex Richardson #include <sys/procfs.h>
525d2d083cSXin LI #include <sys/ptrace.h>
532b75c8adSJohn Baldwin #include <sys/resource.h>
546019514bSAlex Richardson #include <sys/sched.h>
559ddd1412SDag-Erling Smørgrav #include <sys/socket.h>
568207f12dSWarner Losh #define _WANT_FREEBSD11_STAT
572b75c8adSJohn Baldwin #include <sys/stat.h>
5843ce0d90SKonstantin Belousov #include <sys/sysctl.h>
596040822cSAlan Somers #include <sys/time.h>
609ddd1412SDag-Erling Smørgrav #include <sys/un.h>
6134763d1cSJohn Baldwin #include <sys/wait.h>
629ddd1412SDag-Erling Smørgrav #include <netinet/in.h>
634d7b9809SMichael Tuexen #include <netinet/sctp.h>
649ddd1412SDag-Erling Smørgrav #include <arpa/inet.h>
659ddd1412SDag-Erling Smørgrav 
661175b23fSJohn Baldwin #include <assert.h>
67dec17687SBrian Feldman #include <ctype.h>
683cf51049SPhilippe Charnier #include <err.h>
69caa449b6SJohn Baldwin #define _WANT_KERNEL_ERRNO
70caa449b6SJohn Baldwin #include <errno.h>
71894b8f7aSAlfred Perlstein #include <fcntl.h>
729ddd1412SDag-Erling Smørgrav #include <signal.h>
73808d9805SEd Schouten #include <stdbool.h>
74cf0ee873SKonstantin Belousov #include <stddef.h>
75bbeaf6c0SSean Eric Fagan #include <stdio.h>
76bbeaf6c0SSean Eric Fagan #include <stdlib.h>
77bbeaf6c0SSean Eric Fagan #include <string.h>
78d6fb4894SJohn Baldwin #include <sysdecode.h>
79bbeaf6c0SSean Eric Fagan #include <unistd.h>
80081e5c48SPav Lucistnik #include <vis.h>
819ddd1412SDag-Erling Smørgrav 
82ec0bed25SMatthew N. Dodd #include "truss.h"
831be5d704SMark Murray #include "extern.h"
84bbeaf6c0SSean Eric Fagan #include "syscall.h"
85bbeaf6c0SSean Eric Fagan 
86bbeaf6c0SSean Eric Fagan /*
87081e5c48SPav Lucistnik  * This should probably be in its own file, sorted alphabetically.
886019514bSAlex Richardson  *
896019514bSAlex Richardson  * Note: We only scan this table on the initial syscall number to calling
906019514bSAlex Richardson  * convention lookup, i.e. once each time a new syscall is encountered. This
916019514bSAlex Richardson  * is unlikely to be a performance issue, but if it is we could sort this array
926019514bSAlex Richardson  * and use a binary search instead.
93bbeaf6c0SSean Eric Fagan  */
946019514bSAlex Richardson static const struct syscall_decode decoded_syscalls[] = {
95f44fc79dSJohn Baldwin 	/* Native ABI */
967ce44f08SJohn Baldwin 	{ .name = "__acl_aclcheck_fd", .ret_type = 1, .nargs = 3,
977ce44f08SJohn Baldwin 	  .args = { { Int, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
987ce44f08SJohn Baldwin 	{ .name = "__acl_aclcheck_file", .ret_type = 1, .nargs = 3,
997ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1007ce44f08SJohn Baldwin 	{ .name = "__acl_aclcheck_link", .ret_type = 1, .nargs = 3,
1017ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1027ce44f08SJohn Baldwin 	{ .name = "__acl_delete_fd", .ret_type = 1, .nargs = 2,
1037ce44f08SJohn Baldwin 	  .args = { { Int, 0 }, { Acltype, 1 } } },
1047ce44f08SJohn Baldwin 	{ .name = "__acl_delete_file", .ret_type = 1, .nargs = 2,
1057ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 } } },
1067ce44f08SJohn Baldwin 	{ .name = "__acl_delete_link", .ret_type = 1, .nargs = 2,
1077ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 } } },
1087ce44f08SJohn Baldwin 	{ .name = "__acl_get_fd", .ret_type = 1, .nargs = 3,
1097ce44f08SJohn Baldwin 	  .args = { { Int, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1107ce44f08SJohn Baldwin 	{ .name = "__acl_get_file", .ret_type = 1, .nargs = 3,
1117ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1127ce44f08SJohn Baldwin 	{ .name = "__acl_get_link", .ret_type = 1, .nargs = 3,
1137ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1147ce44f08SJohn Baldwin 	{ .name = "__acl_set_fd", .ret_type = 1, .nargs = 3,
1157ce44f08SJohn Baldwin 	  .args = { { Int, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1167ce44f08SJohn Baldwin 	{ .name = "__acl_set_file", .ret_type = 1, .nargs = 3,
1177ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1187ce44f08SJohn Baldwin 	{ .name = "__acl_set_link", .ret_type = 1, .nargs = 3,
1197ce44f08SJohn Baldwin 	  .args = { { Name, 0 }, { Acltype, 1 }, { Ptr, 2 } } },
1207136a1d9SJohn Baldwin 	{ .name = "__cap_rights_get", .ret_type = 1, .nargs = 3,
1217136a1d9SJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { CapRights | OUT, 2 } } },
122f44fc79dSJohn Baldwin 	{ .name = "__getcwd", .ret_type = 1, .nargs = 2,
123f44fc79dSJohn Baldwin 	  .args = { { Name | OUT, 0 }, { Int, 1 } } },
1240573d0a9SMateusz Guzik 	{ .name = "__realpathat", .ret_type = 1, .nargs = 5,
1250573d0a9SMateusz Guzik 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Name | OUT, 2 },
1260573d0a9SMateusz Guzik 		    { Sizet, 3 }, { Int, 4} } },
127f44fc79dSJohn Baldwin 	{ .name = "_umtx_op", .ret_type = 1, .nargs = 5,
128f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 },
129f44fc79dSJohn Baldwin 		    { Ptr, 4 } } },
130f44fc79dSJohn Baldwin 	{ .name = "accept", .ret_type = 1, .nargs = 3,
131f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
132f44fc79dSJohn Baldwin 	{ .name = "access", .ret_type = 1, .nargs = 2,
133f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Accessmode, 1 } } },
134bb24ee2bSThomas Munro 	{ .name = "aio_cancel", .ret_type = 1, .nargs = 2,
135bb24ee2bSThomas Munro 	  .args = { { Int, 0 }, { Aiocb, 1 } } },
136bb24ee2bSThomas Munro 	{ .name = "aio_error", .ret_type = 1, .nargs = 1,
137bb24ee2bSThomas Munro 	  .args = { { Aiocb, 0 } } },
138bb24ee2bSThomas Munro 	{ .name = "aio_fsync", .ret_type = 1, .nargs = 2,
139bb24ee2bSThomas Munro 	  .args = { { AiofsyncOp, 0 }, { Aiocb, 1 } } },
140bb24ee2bSThomas Munro 	{ .name = "aio_mlock", .ret_type = 1, .nargs = 1,
141bb24ee2bSThomas Munro 	  .args = { { Aiocb, 0 } } },
142bb24ee2bSThomas Munro 	{ .name = "aio_read", .ret_type = 1, .nargs = 1,
143bb24ee2bSThomas Munro 	  .args = { { Aiocb, 0 } } },
144bb24ee2bSThomas Munro 	{ .name = "aio_return", .ret_type = 1, .nargs = 1,
145bb24ee2bSThomas Munro 	  .args = { { Aiocb, 0 } } },
146bb24ee2bSThomas Munro 	{ .name = "aio_suspend", .ret_type = 1, .nargs = 3,
147bb24ee2bSThomas Munro 	  .args = { { AiocbArray, 0 }, { Int, 1 }, { Timespec, 2 } } },
148bb24ee2bSThomas Munro 	{ .name = "aio_waitcomplete", .ret_type = 1, .nargs = 2,
149bb24ee2bSThomas Munro 	  .args = { { AiocbPointer | OUT, 0 }, { Timespec, 1 } } },
150bb24ee2bSThomas Munro 	{ .name = "aio_write", .ret_type = 1, .nargs = 1,
151bb24ee2bSThomas Munro 	  .args = { { Aiocb, 0 } } },
152f44fc79dSJohn Baldwin 	{ .name = "bind", .ret_type = 1, .nargs = 3,
15358227c60SMichael Tuexen 	  .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Socklent, 2 } } },
154f44fc79dSJohn Baldwin 	{ .name = "bindat", .ret_type = 1, .nargs = 4,
155f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 },
1567d897327SJohn Baldwin 		    { Int, 3 } } },
157f44fc79dSJohn Baldwin 	{ .name = "break", .ret_type = 1, .nargs = 1,
158f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 } } },
159bed418c8SJohn Baldwin 	{ .name = "cap_fcntls_get", .ret_type = 1, .nargs = 2,
160bed418c8SJohn Baldwin 	  .args = { { Int, 0 }, { CapFcntlRights | OUT, 1 } } },
161bed418c8SJohn Baldwin 	{ .name = "cap_fcntls_limit", .ret_type = 1, .nargs = 2,
162bed418c8SJohn Baldwin 	  .args = { { Int, 0 }, { CapFcntlRights, 1 } } },
163ebb2cc40SJohn Baldwin 	{ .name = "cap_getmode", .ret_type = 1, .nargs = 1,
164ebb2cc40SJohn Baldwin 	  .args = { { PUInt | OUT, 0 } } },
1657136a1d9SJohn Baldwin 	{ .name = "cap_rights_limit", .ret_type = 1, .nargs = 2,
1667136a1d9SJohn Baldwin 	  .args = { { Int, 0 }, { CapRights, 1 } } },
167f44fc79dSJohn Baldwin 	{ .name = "chdir", .ret_type = 1, .nargs = 1,
168f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
169f44fc79dSJohn Baldwin 	{ .name = "chflags", .ret_type = 1, .nargs = 2,
17027459358SJohn Baldwin 	  .args = { { Name | IN, 0 }, { FileFlags, 1 } } },
17127459358SJohn Baldwin 	{ .name = "chflagsat", .ret_type = 1, .nargs = 4,
17227459358SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { FileFlags, 2 },
17327459358SJohn Baldwin 		    { Atflags, 3 } } },
174f44fc79dSJohn Baldwin 	{ .name = "chmod", .ret_type = 1, .nargs = 2,
175ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Octal, 1 } } },
176f44fc79dSJohn Baldwin 	{ .name = "chown", .ret_type = 1, .nargs = 3,
177f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
178f44fc79dSJohn Baldwin 	{ .name = "chroot", .ret_type = 1, .nargs = 1,
179f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
180f44fc79dSJohn Baldwin 	{ .name = "clock_gettime", .ret_type = 1, .nargs = 2,
181f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timespec | OUT, 1 } } },
182ee3b0f6eSDiomidis Spinellis 	{ .name = "close", .ret_type = 1, .nargs = 1,
183ee3b0f6eSDiomidis Spinellis 	  .args = { { Int, 0 } } },
1847be2c6f3SChristian S.J. Peron 	{ .name = "closefrom", .ret_type = 1, .nargs = 1,
1857be2c6f3SChristian S.J. Peron 	  .args = { { Int, 0 } } },
186f3f3e3c4SMateusz Guzik 	{ .name = "close_range", .ret_type = 1, .nargs = 3,
187f3f3e3c4SMateusz Guzik 	  .args = { { Int, 0 }, { Int, 1 }, { Closerangeflags, 2 } } },
1881b224b09SWarner Losh 	{ .name = "compat11.fstat", .ret_type = 1, .nargs = 2,
1891b224b09SWarner Losh 	  .args = { { Int, 0 }, { Stat11 | OUT, 1 } } },
19075a14d22SMark Johnston 	{ .name = "compat11.fstatat", .ret_type = 1, .nargs = 4,
19175a14d22SMark Johnston 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat11 | OUT, 2 },
19275a14d22SMark Johnston 		    { Atflags, 3 } } },
193ffb66079SJohn Baldwin 	{ .name = "compat11.kevent", .ret_type = 1, .nargs = 6,
194ffb66079SJohn Baldwin 	  .args = { { Int, 0 }, { Kevent11, 1 }, { Int, 2 },
195ffb66079SJohn Baldwin 		    { Kevent11 | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } },
1961b224b09SWarner Losh 	{ .name = "compat11.lstat", .ret_type = 1, .nargs = 2,
1971b224b09SWarner Losh 	  .args = { { Name | IN, 0 }, { Stat11 | OUT, 1 } } },
198cd497bd4SMark Johnston 	{ .name = "compat11.mknod", .ret_type = 1, .nargs = 3,
199cd497bd4SMark Johnston 	  .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } },
200cd497bd4SMark Johnston 	{ .name = "compat11.mknodat", .ret_type = 1, .nargs = 4,
201cd497bd4SMark Johnston 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } },
2021b224b09SWarner Losh 	{ .name = "compat11.stat", .ret_type = 1, .nargs = 2,
2031b224b09SWarner Losh 	  .args = { { Name | IN, 0 }, { Stat11 | OUT, 1 } } },
204f44fc79dSJohn Baldwin 	{ .name = "connect", .ret_type = 1, .nargs = 3,
20558227c60SMichael Tuexen 	  .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Socklent, 2 } } },
206f44fc79dSJohn Baldwin 	{ .name = "connectat", .ret_type = 1, .nargs = 4,
207f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 },
208f44fc79dSJohn Baldwin 		    { Int, 3 } } },
209b60a095bSJohn Baldwin 	{ .name = "dup", .ret_type = 1, .nargs = 1,
210b60a095bSJohn Baldwin 	  .args = { { Int, 0 } } },
211b60a095bSJohn Baldwin 	{ .name = "dup2", .ret_type = 1, .nargs = 2,
212b60a095bSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 } } },
213f44fc79dSJohn Baldwin 	{ .name = "eaccess", .ret_type = 1, .nargs = 2,
214f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Accessmode, 1 } } },
215f44fc79dSJohn Baldwin 	{ .name = "execve", .ret_type = 1, .nargs = 3,
216f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
217f44fc79dSJohn Baldwin 		    { ExecEnv | IN, 2 } } },
218f44fc79dSJohn Baldwin 	{ .name = "exit", .ret_type = 0, .nargs = 1,
219f44fc79dSJohn Baldwin 	  .args = { { Hex, 0 } } },
22026606dcaSJohn Baldwin 	{ .name = "extattr_delete_fd", .ret_type = 1, .nargs = 3,
22126606dcaSJohn Baldwin 	  .args = { { Int, 0 }, { Extattrnamespace, 1 }, { Name, 2 } } },
22226606dcaSJohn Baldwin 	{ .name = "extattr_delete_file", .ret_type = 1, .nargs = 3,
22326606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { Name, 2 } } },
22426606dcaSJohn Baldwin 	{ .name = "extattr_delete_link", .ret_type = 1, .nargs = 3,
22526606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { Name, 2 } } },
22626606dcaSJohn Baldwin 	{ .name = "extattr_get_fd", .ret_type = 1, .nargs = 5,
22726606dcaSJohn Baldwin 	  .args = { { Int, 0 }, { Extattrnamespace, 1 }, { Name, 2 },
22826606dcaSJohn Baldwin 		    { BinString | OUT, 3 }, { Sizet, 4 } } },
22926606dcaSJohn Baldwin 	{ .name = "extattr_get_file", .ret_type = 1, .nargs = 5,
23026606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { Name, 2 },
23126606dcaSJohn Baldwin 		    { BinString | OUT, 3 }, { Sizet, 4 } } },
23226606dcaSJohn Baldwin 	{ .name = "extattr_get_link", .ret_type = 1, .nargs = 5,
23326606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { Name, 2 },
23426606dcaSJohn Baldwin 		    { BinString | OUT, 3 }, { Sizet, 4 } } },
23526606dcaSJohn Baldwin 	{ .name = "extattr_list_fd", .ret_type = 1, .nargs = 4,
23626606dcaSJohn Baldwin 	  .args = { { Int, 0 }, { Extattrnamespace, 1 }, { BinString | OUT, 2 },
23726606dcaSJohn Baldwin 		    { Sizet, 3 } } },
23826606dcaSJohn Baldwin 	{ .name = "extattr_list_file", .ret_type = 1, .nargs = 4,
23926606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { BinString | OUT, 2 },
24026606dcaSJohn Baldwin 		    { Sizet, 3 } } },
24126606dcaSJohn Baldwin 	{ .name = "extattr_list_link", .ret_type = 1, .nargs = 4,
24226606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { BinString | OUT, 2 },
24326606dcaSJohn Baldwin 		    { Sizet, 3 } } },
24426606dcaSJohn Baldwin 	{ .name = "extattr_set_fd", .ret_type = 1, .nargs = 5,
24526606dcaSJohn Baldwin 	  .args = { { Int, 0 }, { Extattrnamespace, 1 }, { Name, 2 },
24626606dcaSJohn Baldwin 		    { BinString | IN, 3 }, { Sizet, 4 } } },
24726606dcaSJohn Baldwin 	{ .name = "extattr_set_file", .ret_type = 1, .nargs = 5,
24826606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { Name, 2 },
24926606dcaSJohn Baldwin 		    { BinString | IN, 3 }, { Sizet, 4 } } },
25026606dcaSJohn Baldwin 	{ .name = "extattr_set_link", .ret_type = 1, .nargs = 5,
25126606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Extattrnamespace, 1 }, { Name, 2 },
25226606dcaSJohn Baldwin 		    { BinString | IN, 3 }, { Sizet, 4 } } },
25326606dcaSJohn Baldwin 	{ .name = "extattrctl", .ret_type = 1, .nargs = 5,
25426606dcaSJohn Baldwin 	  .args = { { Name, 0 }, { Hex, 1 }, { Name, 2 },
25526606dcaSJohn Baldwin 		    { Extattrnamespace, 3 }, { Name, 4 } } },
256f44fc79dSJohn Baldwin 	{ .name = "faccessat", .ret_type = 1, .nargs = 4,
257f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 },
258f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
25927459358SJohn Baldwin 	{ .name = "fchflags", .ret_type = 1, .nargs = 2,
26027459358SJohn Baldwin 	  .args = { { Int, 0 }, { FileFlags, 1 } } },
261f44fc79dSJohn Baldwin 	{ .name = "fchmod", .ret_type = 1, .nargs = 2,
262f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Octal, 1 } } },
263f44fc79dSJohn Baldwin 	{ .name = "fchmodat", .ret_type = 1, .nargs = 4,
264f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Atflags, 3 } } },
265f44fc79dSJohn Baldwin 	{ .name = "fchown", .ret_type = 1, .nargs = 3,
266f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } },
267f44fc79dSJohn Baldwin 	{ .name = "fchownat", .ret_type = 1, .nargs = 5,
268f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 },
269f44fc79dSJohn Baldwin 		    { Atflags, 4 } } },
270f44fc79dSJohn Baldwin 	{ .name = "fcntl", .ret_type = 1, .nargs = 3,
271f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } },
272b5eab9d4SThomas Munro 	{ .name = "fdatasync", .ret_type = 1, .nargs = 1,
273b5eab9d4SThomas Munro 	  .args = { { Int, 0 } } },
274dd92181fSJohn Baldwin 	{ .name = "flock", .ret_type = 1, .nargs = 2,
275dd92181fSJohn Baldwin 	  .args = { { Int, 0 }, { Flockop, 1 } } },
276f44fc79dSJohn Baldwin 	{ .name = "fstat", .ret_type = 1, .nargs = 2,
277f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Stat | OUT, 1 } } },
278f44fc79dSJohn Baldwin 	{ .name = "fstatat", .ret_type = 1, .nargs = 4,
279f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat | OUT, 2 },
280f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
281f44fc79dSJohn Baldwin 	{ .name = "fstatfs", .ret_type = 1, .nargs = 2,
282f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { StatFs | OUT, 1 } } },
283b5eab9d4SThomas Munro 	{ .name = "fsync", .ret_type = 1, .nargs = 1,
284b5eab9d4SThomas Munro 	  .args = { { Int, 0 } } },
285f44fc79dSJohn Baldwin 	{ .name = "ftruncate", .ret_type = 1, .nargs = 2,
286c05cc0d6SJohn Baldwin 	  .args = { { Int | IN, 0 }, { QuadHex | IN, 1 } } },
287f44fc79dSJohn Baldwin 	{ .name = "futimens", .ret_type = 1, .nargs = 2,
288f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timespec2 | IN, 1 } } },
289f44fc79dSJohn Baldwin 	{ .name = "futimes", .ret_type = 1, .nargs = 2,
290f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Timeval2 | IN, 1 } } },
291f44fc79dSJohn Baldwin 	{ .name = "futimesat", .ret_type = 1, .nargs = 3,
292f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timeval2 | IN, 2 } } },
293b60a095bSJohn Baldwin 	{ .name = "getdirentries", .ret_type = 1, .nargs = 4,
294b60a095bSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 },
295b60a095bSJohn Baldwin 		    { PQuadHex | OUT, 3 } } },
296ab43bedcSJohn Baldwin 	{ .name = "getfsstat", .ret_type = 1, .nargs = 3,
297ab43bedcSJohn Baldwin 	  .args = { { Ptr, 0 }, { Long, 1 }, { Getfsstatmode, 2 } } },
298f44fc79dSJohn Baldwin 	{ .name = "getitimer", .ret_type = 1, .nargs = 2,
299*b9b86b67SDmitry Chagin 	  .args = { { Itimerwhich, 0 }, { Itimerval | OUT, 2 } } },
300f44fc79dSJohn Baldwin 	{ .name = "getpeername", .ret_type = 1, .nargs = 3,
301f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
302f44fc79dSJohn Baldwin 	{ .name = "getpgid", .ret_type = 1, .nargs = 1,
303f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
304ad419d33SJohn Baldwin 	{ .name = "getpriority", .ret_type = 1, .nargs = 2,
305ad419d33SJohn Baldwin 	  .args = { { Priowhich, 0 }, { Int, 1 } } },
306e9ac2743SConrad Meyer 	{ .name = "getrandom", .ret_type = 1, .nargs = 3,
307e9ac2743SConrad Meyer 	  .args = { { BinString | OUT, 0 }, { Sizet, 1 }, { UInt, 2 } } },
308f44fc79dSJohn Baldwin 	{ .name = "getrlimit", .ret_type = 1, .nargs = 2,
309f44fc79dSJohn Baldwin 	  .args = { { Resource, 0 }, { Rlimit | OUT, 1 } } },
310f44fc79dSJohn Baldwin 	{ .name = "getrusage", .ret_type = 1, .nargs = 2,
311ee8aa41dSJohn Baldwin 	  .args = { { RusageWho, 0 }, { Rusage | OUT, 1 } } },
312f44fc79dSJohn Baldwin 	{ .name = "getsid", .ret_type = 1, .nargs = 1,
313f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
314f44fc79dSJohn Baldwin 	{ .name = "getsockname", .ret_type = 1, .nargs = 3,
315f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
316832af457SMichael Tuexen 	{ .name = "getsockopt", .ret_type = 1, .nargs = 5,
317832af457SMichael Tuexen 	  .args = { { Int, 0 }, { Sockoptlevel, 1 }, { Sockoptname, 2 },
318832af457SMichael Tuexen 		    { Ptr | OUT, 3 }, { Ptr | OUT, 4 } } },
319f44fc79dSJohn Baldwin 	{ .name = "gettimeofday", .ret_type = 1, .nargs = 2,
320f44fc79dSJohn Baldwin 	  .args = { { Timeval | OUT, 0 }, { Ptr, 1 } } },
321f44fc79dSJohn Baldwin 	{ .name = "ioctl", .ret_type = 1, .nargs = 3,
322a776eeafSJohn Baldwin 	  .args = { { Int, 0 }, { Ioctl, 1 }, { Ptr, 2 } } },
323f44fc79dSJohn Baldwin 	{ .name = "kevent", .ret_type = 1, .nargs = 6,
324f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 },
325f44fc79dSJohn Baldwin 		    { Int, 4 }, { Timespec, 5 } } },
326f44fc79dSJohn Baldwin 	{ .name = "kill", .ret_type = 1, .nargs = 2,
327f44fc79dSJohn Baldwin 	  .args = { { Int | IN, 0 }, { Signal | IN, 1 } } },
328f44fc79dSJohn Baldwin 	{ .name = "kldfind", .ret_type = 1, .nargs = 1,
329f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
330f44fc79dSJohn Baldwin 	{ .name = "kldfirstmod", .ret_type = 1, .nargs = 1,
331f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
332f44fc79dSJohn Baldwin 	{ .name = "kldload", .ret_type = 1, .nargs = 1,
333f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
334f44fc79dSJohn Baldwin 	{ .name = "kldnext", .ret_type = 1, .nargs = 1,
335f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
336f44fc79dSJohn Baldwin 	{ .name = "kldstat", .ret_type = 1, .nargs = 2,
337f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr, 1 } } },
33894e854c5SJohn Baldwin 	{ .name = "kldsym", .ret_type = 1, .nargs = 3,
33994e854c5SJohn Baldwin 	  .args = { { Int, 0 }, { Kldsymcmd, 1 }, { Ptr, 2 } } },
340f44fc79dSJohn Baldwin 	{ .name = "kldunload", .ret_type = 1, .nargs = 1,
341f44fc79dSJohn Baldwin 	  .args = { { Int, 0 } } },
34294e854c5SJohn Baldwin 	{ .name = "kldunloadf", .ret_type = 1, .nargs = 2,
34394e854c5SJohn Baldwin 	  .args = { { Int, 0 }, { Kldunloadflags, 1 } } },
344f44fc79dSJohn Baldwin 	{ .name = "kse_release", .ret_type = 0, .nargs = 1,
345f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
346f44fc79dSJohn Baldwin 	{ .name = "lchflags", .ret_type = 1, .nargs = 2,
34727459358SJohn Baldwin 	  .args = { { Name | IN, 0 }, { FileFlags, 1 } } },
348f44fc79dSJohn Baldwin 	{ .name = "lchmod", .ret_type = 1, .nargs = 2,
349f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
350f44fc79dSJohn Baldwin 	{ .name = "lchown", .ret_type = 1, .nargs = 3,
351f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
3522b75c8adSJohn Baldwin 	{ .name = "link", .ret_type = 1, .nargs = 2,
353ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
3542b75c8adSJohn Baldwin 	{ .name = "linkat", .ret_type = 1, .nargs = 5,
3557d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 },
3567d897327SJohn Baldwin 		    { Atflags, 4 } } },
357bb24ee2bSThomas Munro 	{ .name = "lio_listio", .ret_type = 1, .nargs = 4,
358bb24ee2bSThomas Munro 	  .args = { { LioMode, 0 }, { AiocbArray, 1 }, { Int, 2 },
359bb24ee2bSThomas Munro 		    { Sigevent, 3 } } },
360e8d2c81dSMichael Tuexen 	{ .name = "listen", .ret_type = 1, .nargs = 2,
361e8d2c81dSMichael Tuexen 	  .args = { { Int, 0 }, { Int, 1 } } },
362f44fc79dSJohn Baldwin  	{ .name = "lseek", .ret_type = 2, .nargs = 3,
363c05cc0d6SJohn Baldwin 	  .args = { { Int, 0 }, { QuadHex, 1 }, { Whence, 2 } } },
364f44fc79dSJohn Baldwin 	{ .name = "lstat", .ret_type = 1, .nargs = 2,
365f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
366f44fc79dSJohn Baldwin 	{ .name = "lutimes", .ret_type = 1, .nargs = 2,
367f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
36898fdbeecSJohn Baldwin 	{ .name = "madvise", .ret_type = 1, .nargs = 3,
36998fdbeecSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Madvice, 2 } } },
3702d9c9988SJohn Baldwin 	{ .name = "minherit", .ret_type = 1, .nargs = 3,
3712d9c9988SJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Minherit, 2 } } },
372f44fc79dSJohn Baldwin 	{ .name = "mkdir", .ret_type = 1, .nargs = 2,
373f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
374f44fc79dSJohn Baldwin 	{ .name = "mkdirat", .ret_type = 1, .nargs = 3,
375f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
3762b75c8adSJohn Baldwin 	{ .name = "mkfifo", .ret_type = 1, .nargs = 2,
377e82ce59cSJohn Baldwin 	  .args = { { Name, 0 }, { Octal, 1 } } },
3782b75c8adSJohn Baldwin 	{ .name = "mkfifoat", .ret_type = 1, .nargs = 3,
3797d897327SJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } },
3802b75c8adSJohn Baldwin 	{ .name = "mknod", .ret_type = 1, .nargs = 3,
381cd497bd4SMark Johnston 	  .args = { { Name, 0 }, { Octal, 1 }, { Quad, 2 } } },
3822b75c8adSJohn Baldwin 	{ .name = "mknodat", .ret_type = 1, .nargs = 4,
383cd497bd4SMark Johnston 	  .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Quad, 3 } } },
38494bde755SJohn Baldwin 	{ .name = "mlock", .ret_type = 1, .nargs = 2,
38594bde755SJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 } } },
38694bde755SJohn Baldwin 	{ .name = "mlockall", .ret_type = 1, .nargs = 1,
38794bde755SJohn Baldwin 	  .args = { { Mlockall, 0 } } },
388f44fc79dSJohn Baldwin 	{ .name = "mmap", .ret_type = 1, .nargs = 6,
389e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Mprot, 2 }, { Mmapflags, 3 },
390c05cc0d6SJohn Baldwin 		    { Int, 4 }, { QuadHex, 5 } } },
391f44fc79dSJohn Baldwin 	{ .name = "modfind", .ret_type = 1, .nargs = 1,
392f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 } } },
3932b75c8adSJohn Baldwin 	{ .name = "mount", .ret_type = 1, .nargs = 4,
3948acc8e78SJohn Baldwin 	  .args = { { Name, 0 }, { Name, 1 }, { Mountflags, 2 }, { Ptr, 3 } } },
395f44fc79dSJohn Baldwin 	{ .name = "mprotect", .ret_type = 1, .nargs = 3,
396e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Mprot, 2 } } },
397114aeee0SJohn Baldwin 	{ .name = "msync", .ret_type = 1, .nargs = 3,
398114aeee0SJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 }, { Msync, 2 } } },
39994bde755SJohn Baldwin 	{ .name = "munlock", .ret_type = 1, .nargs = 2,
40094bde755SJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 } } },
401f44fc79dSJohn Baldwin 	{ .name = "munmap", .ret_type = 1, .nargs = 2,
402e261fb2aSJohn Baldwin 	  .args = { { Ptr, 0 }, { Sizet, 1 } } },
403f44fc79dSJohn Baldwin 	{ .name = "nanosleep", .ret_type = 1, .nargs = 1,
404f44fc79dSJohn Baldwin 	  .args = { { Timespec, 0 } } },
4058acc8e78SJohn Baldwin 	{ .name = "nmount", .ret_type = 1, .nargs = 3,
4068acc8e78SJohn Baldwin 	  .args = { { Ptr, 0 }, { UInt, 1 }, { Mountflags, 2 } } },
407f44fc79dSJohn Baldwin 	{ .name = "open", .ret_type = 1, .nargs = 3,
408f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } },
409f44fc79dSJohn Baldwin 	{ .name = "openat", .ret_type = 1, .nargs = 4,
410f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Open, 2 },
411f44fc79dSJohn Baldwin 		    { Octal, 3 } } },
412f44fc79dSJohn Baldwin 	{ .name = "pathconf", .ret_type = 1, .nargs = 2,
413f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Pathconf, 1 } } },
414f44fc79dSJohn Baldwin 	{ .name = "pipe", .ret_type = 1, .nargs = 1,
415f44fc79dSJohn Baldwin 	  .args = { { PipeFds | OUT, 0 } } },
416f44fc79dSJohn Baldwin 	{ .name = "pipe2", .ret_type = 1, .nargs = 2,
4179289f547SJohn Baldwin 	  .args = { { Ptr, 0 }, { Pipe2, 1 } } },
418f44fc79dSJohn Baldwin 	{ .name = "poll", .ret_type = 1, .nargs = 3,
419f44fc79dSJohn Baldwin 	  .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } },
420d2a97485SJohn Baldwin 	{ .name = "posix_fadvise", .ret_type = 1, .nargs = 4,
421d2a97485SJohn Baldwin 	  .args = { { Int, 0 }, { QuadHex, 1 }, { QuadHex, 2 },
422d2a97485SJohn Baldwin 		    { Fadvice, 3 } } },
423f44fc79dSJohn Baldwin 	{ .name = "posix_openpt", .ret_type = 1, .nargs = 1,
424f44fc79dSJohn Baldwin 	  .args = { { Open, 0 } } },
4259bf4983fSChristian Weisgerber 	{ .name = "ppoll", .ret_type = 1, .nargs = 4,
4269bf4983fSChristian Weisgerber 	  .args = { { Pollfd, 0 }, { Int, 1 }, { Timespec | IN, 2 },
4279bf4983fSChristian Weisgerber  		    { Sigset | IN, 3 } } },
428b60a095bSJohn Baldwin 	{ .name = "pread", .ret_type = 1, .nargs = 4,
429b60a095bSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 },
430b60a095bSJohn Baldwin 		    { QuadHex, 3 } } },
431f44fc79dSJohn Baldwin 	{ .name = "procctl", .ret_type = 1, .nargs = 4,
432c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { Procctl, 2 }, { Ptr, 3 } } },
4335ac1c7acSJohn Baldwin 	{ .name = "ptrace", .ret_type = 1, .nargs = 4,
4345ac1c7acSJohn Baldwin 	  .args = { { Ptraceop, 0 }, { Int, 1 }, { Ptr, 2 }, { Int, 3 } } },
435b60a095bSJohn Baldwin 	{ .name = "pwrite", .ret_type = 1, .nargs = 4,
436b60a095bSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 },
437b60a095bSJohn Baldwin 		    { QuadHex, 3 } } },
438dd0c462cSJohn Baldwin 	{ .name = "quotactl", .ret_type = 1, .nargs = 4,
439dd0c462cSJohn Baldwin 	  .args = { { Name, 0 }, { Quotactlcmd, 1 }, { Int, 2 }, { Ptr, 3 } } },
440f44fc79dSJohn Baldwin 	{ .name = "read", .ret_type = 1, .nargs = 3,
441e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 } } },
442f44fc79dSJohn Baldwin 	{ .name = "readlink", .ret_type = 1, .nargs = 3,
443e261fb2aSJohn Baldwin 	  .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Sizet, 2 } } },
444f44fc79dSJohn Baldwin 	{ .name = "readlinkat", .ret_type = 1, .nargs = 4,
445f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 },
446e261fb2aSJohn Baldwin 		    { Sizet, 3 } } },
447097b25a7SMichael Tuexen 	{ .name = "readv", .ret_type = 1, .nargs = 3,
448097b25a7SMichael Tuexen 	  .args = { { Int, 0 }, { Iovec | OUT, 1 }, { Int, 2 } } },
4494152441fSJohn Baldwin 	{ .name = "reboot", .ret_type = 1, .nargs = 1,
4504152441fSJohn Baldwin 	  .args = { { Reboothowto, 0 } } },
451ee3b0f6eSDiomidis Spinellis 	{ .name = "recvfrom", .ret_type = 1, .nargs = 6,
4528b429b65SMichael Tuexen 	  .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 },
4538b429b65SMichael Tuexen 	            { Msgflags, 3 }, { Sockaddr | OUT, 4 },
4548b429b65SMichael Tuexen 	            { Ptr | OUT, 5 } } },
455fca08fe6SMichael Tuexen 	{ .name = "recvmsg", .ret_type = 1, .nargs = 3,
456a2674e03SMichael Tuexen 	  .args = { { Int, 0 }, { Msghdr | OUT, 1 }, { Msgflags, 2 } } },
457f44fc79dSJohn Baldwin 	{ .name = "rename", .ret_type = 1, .nargs = 2,
458f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Name, 1 } } },
459f44fc79dSJohn Baldwin 	{ .name = "renameat", .ret_type = 1, .nargs = 4,
460f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 } } },
461f44fc79dSJohn Baldwin 	{ .name = "rfork", .ret_type = 1, .nargs = 1,
462f44fc79dSJohn Baldwin 	  .args = { { Rforkflags, 0 } } },
463cca89ee3SBryan Drewery 	{ .name = "rmdir", .ret_type = 1, .nargs = 1,
464cca89ee3SBryan Drewery 	  .args = { { Name, 0 } } },
4653cd40bc3SJohn Baldwin 	{ .name = "rtprio", .ret_type = 1, .nargs = 3,
4663cd40bc3SJohn Baldwin 	  .args = { { Rtpriofunc, 0 }, { Int, 1 }, { Ptr, 2 } } },
4673cd40bc3SJohn Baldwin 	{ .name = "rtprio_thread", .ret_type = 1, .nargs = 3,
4683cd40bc3SJohn Baldwin 	  .args = { { Rtpriofunc, 0 }, { Int, 1 }, { Ptr, 2 } } },
469a4110f9fSJohn Baldwin 	{ .name = "sched_get_priority_max", .ret_type = 1, .nargs = 1,
470a4110f9fSJohn Baldwin 	  .args = { { Schedpolicy, 0 } } },
471a4110f9fSJohn Baldwin 	{ .name = "sched_get_priority_min", .ret_type = 1, .nargs = 1,
472a4110f9fSJohn Baldwin 	  .args = { { Schedpolicy, 0 } } },
473a4110f9fSJohn Baldwin 	{ .name = "sched_getparam", .ret_type = 1, .nargs = 2,
474a4110f9fSJohn Baldwin 	  .args = { { Int, 0 }, { Schedparam | OUT, 1 } } },
475a4110f9fSJohn Baldwin 	{ .name = "sched_getscheduler", .ret_type = 1, .nargs = 1,
476a4110f9fSJohn Baldwin 	  .args = { { Int, 0 } } },
477a4110f9fSJohn Baldwin 	{ .name = "sched_rr_get_interval", .ret_type = 1, .nargs = 2,
478a4110f9fSJohn Baldwin 	  .args = { { Int, 0 }, { Timespec | OUT, 1 } } },
479a4110f9fSJohn Baldwin 	{ .name = "sched_setparam", .ret_type = 1, .nargs = 2,
480a4110f9fSJohn Baldwin 	  .args = { { Int, 0 }, { Schedparam, 1 } } },
481a4110f9fSJohn Baldwin 	{ .name = "sched_setscheduler", .ret_type = 1, .nargs = 3,
482a4110f9fSJohn Baldwin 	  .args = { { Int, 0 }, { Schedpolicy, 1 }, { Schedparam, 2 } } },
483c0b72375SMichael Tuexen 	{ .name = "sctp_generic_recvmsg", .ret_type = 1, .nargs = 7,
4844d7b9809SMichael Tuexen 	  .args = { { Int, 0 }, { Iovec | OUT, 1 }, { Int, 2 },
4854d7b9809SMichael Tuexen 	            { Sockaddr | OUT, 3 }, { Ptr | OUT, 4 },
4864d7b9809SMichael Tuexen 	            { Sctpsndrcvinfo | OUT, 5 }, { Ptr | OUT, 6 } } },
487c0b72375SMichael Tuexen 	{ .name = "sctp_generic_sendmsg", .ret_type = 1, .nargs = 7,
488c0b72375SMichael Tuexen 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 },
4894d7b9809SMichael Tuexen 	            { Sockaddr | IN, 3 }, { Socklent, 4 },
4904d7b9809SMichael Tuexen 	            { Sctpsndrcvinfo | IN, 5 }, { Msgflags, 6 } } },
4914d7b9809SMichael Tuexen 	{ .name = "sctp_generic_sendmsg_iov", .ret_type = 1, .nargs = 7,
4924d7b9809SMichael Tuexen 	  .args = { { Int, 0 }, { Iovec | IN, 1 }, { Int, 2 },
4934d7b9809SMichael Tuexen 	            { Sockaddr | IN, 3 }, { Socklent, 4 },
4944d7b9809SMichael Tuexen 	            { Sctpsndrcvinfo | IN, 5 }, { Msgflags, 6 } } },
49590da2c79SMark Johnston 	{ .name = "sendfile", .ret_type = 1, .nargs = 7,
49690da2c79SMark Johnston 	  .args = { { Int, 0 }, { Int, 1 }, { QuadHex, 2 }, { Sizet, 3 },
49790da2c79SMark Johnston 		    { Sendfilehdtr, 4 }, { QuadHex | OUT, 5 },
49890da2c79SMark Johnston 		    { Sendfileflags, 6 } } },
499ee3b0f6eSDiomidis Spinellis 	{ .name = "select", .ret_type = 1, .nargs = 5,
5000a46af44SJohn Baldwin 	  .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 },
5010a46af44SJohn Baldwin 		    { Timeval, 4 } } },
502fca08fe6SMichael Tuexen 	{ .name = "sendmsg", .ret_type = 1, .nargs = 3,
503a2674e03SMichael Tuexen 	  .args = { { Int, 0 }, { Msghdr | IN, 1 }, { Msgflags, 2 } } },
504f44fc79dSJohn Baldwin 	{ .name = "sendto", .ret_type = 1, .nargs = 6,
5058b429b65SMichael Tuexen 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 },
5068b429b65SMichael Tuexen 	            { Msgflags, 3 }, { Sockaddr | IN, 4 },
5078b429b65SMichael Tuexen 	            { Socklent | IN, 5 } } },
508ee3b0f6eSDiomidis Spinellis 	{ .name = "setitimer", .ret_type = 1, .nargs = 3,
509*b9b86b67SDmitry Chagin 	  .args = { { Itimerwhich, 0 }, { Itimerval, 1 },
510*b9b86b67SDmitry Chagin 		    { Itimerval | OUT, 2 } } },
511ad419d33SJohn Baldwin 	{ .name = "setpriority", .ret_type = 1, .nargs = 3,
512ad419d33SJohn Baldwin 	  .args = { { Priowhich, 0 }, { Int, 1 }, { Int, 2 } } },
513f44fc79dSJohn Baldwin 	{ .name = "setrlimit", .ret_type = 1, .nargs = 2,
514f44fc79dSJohn Baldwin 	  .args = { { Resource, 0 }, { Rlimit | IN, 1 } } },
515832af457SMichael Tuexen 	{ .name = "setsockopt", .ret_type = 1, .nargs = 5,
516832af457SMichael Tuexen 	  .args = { { Int, 0 }, { Sockoptlevel, 1 }, { Sockoptname, 2 },
517832af457SMichael Tuexen 		    { Ptr | IN, 3 }, { Socklent, 4 } } },
51824eeedb5SAllan Jude 	{ .name = "shm_open", .ret_type = 1, .nargs = 3,
5195b05dc5aSThomas Munro 	  .args = { { ShmName | IN, 0 }, { Open, 1 }, { Octal, 2 } } },
520bcca3425SKyle Evans 	{ .name = "shm_open2", .ret_type = 1, .nargs = 5,
521bcca3425SKyle Evans 	  .args = { { ShmName | IN, 0 }, { Open, 1 }, { Octal, 2 },
522733ba7efSKyle Evans 		    { ShmFlags, 3 }, { Name | IN, 4 } } },
5239afb12baSDavid Bright 	{ .name = "shm_rename", .ret_type = 1, .nargs = 3,
5249afb12baSDavid Bright 	  .args = { { Name | IN, 0 }, { Name | IN, 1 }, { Hex, 2 } } },
52524eeedb5SAllan Jude 	{ .name = "shm_unlink", .ret_type = 1, .nargs = 1,
52624eeedb5SAllan Jude 	  .args = { { Name | IN, 0 } } },
527f44fc79dSJohn Baldwin 	{ .name = "shutdown", .ret_type = 1, .nargs = 2,
528f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Shutdown, 1 } } },
529f44fc79dSJohn Baldwin 	{ .name = "sigaction", .ret_type = 1, .nargs = 3,
530f44fc79dSJohn Baldwin 	  .args = { { Signal, 0 }, { Sigaction | IN, 1 },
531f44fc79dSJohn Baldwin 		    { Sigaction | OUT, 2 } } },
5322b75c8adSJohn Baldwin 	{ .name = "sigpending", .ret_type = 1, .nargs = 1,
533b289a8d7SJohn Baldwin 	  .args = { { Sigset | OUT, 0 } } },
5342b75c8adSJohn Baldwin 	{ .name = "sigprocmask", .ret_type = 1, .nargs = 3,
535ee3b0f6eSDiomidis Spinellis 	  .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } },
5362b75c8adSJohn Baldwin 	{ .name = "sigqueue", .ret_type = 1, .nargs = 3,
537b289a8d7SJohn Baldwin 	  .args = { { Int, 0 }, { Signal, 1 }, { LongHex, 2 } } },
5382b75c8adSJohn Baldwin 	{ .name = "sigreturn", .ret_type = 1, .nargs = 1,
539b289a8d7SJohn Baldwin 	  .args = { { Ptr, 0 } } },
5402b75c8adSJohn Baldwin 	{ .name = "sigsuspend", .ret_type = 1, .nargs = 1,
541b289a8d7SJohn Baldwin 	  .args = { { Sigset | IN, 0 } } },
542b289a8d7SJohn Baldwin 	{ .name = "sigtimedwait", .ret_type = 1, .nargs = 3,
54313e5e6b6SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Siginfo | OUT, 1 },
54413e5e6b6SJohn Baldwin 		    { Timespec | IN, 2 } } },
545b289a8d7SJohn Baldwin 	{ .name = "sigwait", .ret_type = 1, .nargs = 2,
54613e5e6b6SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { PSig | OUT, 1 } } },
547b289a8d7SJohn Baldwin 	{ .name = "sigwaitinfo", .ret_type = 1, .nargs = 2,
54813e5e6b6SJohn Baldwin 	  .args = { { Sigset | IN, 0 }, { Siginfo | OUT, 1 } } },
549ee3b0f6eSDiomidis Spinellis 	{ .name = "socket", .ret_type = 1, .nargs = 3,
550ecac235bSMichael Tuexen 	  .args = { { Sockdomain, 0 }, { Socktype, 1 }, { Sockprotocol, 2 } } },
551f44fc79dSJohn Baldwin 	{ .name = "stat", .ret_type = 1, .nargs = 2,
552f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
553f44fc79dSJohn Baldwin 	{ .name = "statfs", .ret_type = 1, .nargs = 2,
554f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { StatFs | OUT, 1 } } },
555ee3b0f6eSDiomidis Spinellis 	{ .name = "symlink", .ret_type = 1, .nargs = 2,
556ee3b0f6eSDiomidis Spinellis 	  .args = { { Name, 0 }, { Name, 1 } } },
5577d897327SJohn Baldwin 	{ .name = "symlinkat", .ret_type = 1, .nargs = 3,
5587d897327SJohn Baldwin 	  .args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } },
559f44fc79dSJohn Baldwin 	{ .name = "sysarch", .ret_type = 1, .nargs = 2,
560f44fc79dSJohn Baldwin 	  .args = { { Sysarch, 0 }, { Ptr, 1 } } },
56143ce0d90SKonstantin Belousov 	{ .name = "__sysctl", .ret_type = 1, .nargs = 6,
56243ce0d90SKonstantin Belousov 	  .args = { { Sysctl, 0 }, { Sizet, 1 }, { Ptr, 2 }, { Ptr, 3 },
56343ce0d90SKonstantin Belousov 	            { Ptr, 4 }, { Sizet, 5 } } },
56443ce0d90SKonstantin Belousov 	{ .name = "__sysctlbyname", .ret_type = 1, .nargs = 6,
56543ce0d90SKonstantin Belousov 	  .args = { { Name, 0 }, { Sizet, 1 }, { Ptr, 2 }, { Ptr, 3 },
56643ce0d90SKonstantin Belousov 	            { Ptr, 4}, { Sizet, 5 } } },
567f44fc79dSJohn Baldwin 	{ .name = "thr_kill", .ret_type = 1, .nargs = 2,
568f44fc79dSJohn Baldwin 	  .args = { { Long, 0 }, { Signal, 1 } } },
569f44fc79dSJohn Baldwin 	{ .name = "thr_self", .ret_type = 1, .nargs = 1,
570f44fc79dSJohn Baldwin 	  .args = { { Ptr, 0 } } },
571d86cddf0SJohn Baldwin 	{ .name = "thr_set_name", .ret_type = 1, .nargs = 2,
572d86cddf0SJohn Baldwin 	  .args = { { Long, 0 }, { Name, 1 } } },
573f44fc79dSJohn Baldwin 	{ .name = "truncate", .ret_type = 1, .nargs = 2,
574c05cc0d6SJohn Baldwin 	  .args = { { Name | IN, 0 }, { QuadHex | IN, 1 } } },
575f44fc79dSJohn Baldwin #if 0
576f44fc79dSJohn Baldwin 	/* Does not exist */
577f44fc79dSJohn Baldwin 	{ .name = "umount", .ret_type = 1, .nargs = 2,
578f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Int, 2 } } },
579f44fc79dSJohn Baldwin #endif
580f44fc79dSJohn Baldwin 	{ .name = "unlink", .ret_type = 1, .nargs = 1,
581f44fc79dSJohn Baldwin 	  .args = { { Name, 0 } } },
582f44fc79dSJohn Baldwin 	{ .name = "unlinkat", .ret_type = 1, .nargs = 3,
583f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } },
584f44fc79dSJohn Baldwin 	{ .name = "unmount", .ret_type = 1, .nargs = 2,
5858acc8e78SJohn Baldwin 	  .args = { { Name, 0 }, { Mountflags, 1 } } },
586f44fc79dSJohn Baldwin 	{ .name = "utimensat", .ret_type = 1, .nargs = 4,
587f44fc79dSJohn Baldwin 	  .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 },
588f44fc79dSJohn Baldwin 		    { Atflags, 3 } } },
589f44fc79dSJohn Baldwin 	{ .name = "utimes", .ret_type = 1, .nargs = 2,
590f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
591195aef99SBryan Drewery 	{ .name = "utrace", .ret_type = 1, .nargs = 1,
592195aef99SBryan Drewery 	  .args = { { Utrace, 0 } } },
59334763d1cSJohn Baldwin 	{ .name = "wait4", .ret_type = 1, .nargs = 4,
59434763d1cSJohn Baldwin 	  .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 },
59534763d1cSJohn Baldwin 		    { Rusage | OUT, 3 } } },
59634763d1cSJohn Baldwin 	{ .name = "wait6", .ret_type = 1, .nargs = 6,
597c05cc0d6SJohn Baldwin 	  .args = { { Idtype, 0 }, { Quad, 1 }, { ExitStatus | OUT, 2 },
59813e5e6b6SJohn Baldwin 		    { Waitoptions, 3 }, { Rusage | OUT, 4 },
59913e5e6b6SJohn Baldwin 		    { Siginfo | OUT, 5 } } },
600f44fc79dSJohn Baldwin 	{ .name = "write", .ret_type = 1, .nargs = 3,
601e261fb2aSJohn Baldwin 	  .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 } } },
602ee6e58b2SMichael Tuexen 	{ .name = "writev", .ret_type = 1, .nargs = 3,
603dfcd2888SMichael Tuexen 	  .args = { { Int, 0 }, { Iovec | IN, 1 }, { Int, 2 } } },
604f44fc79dSJohn Baldwin 
605f44fc79dSJohn Baldwin 	/* Linux ABI */
606f44fc79dSJohn Baldwin 	{ .name = "linux_access", .ret_type = 1, .nargs = 2,
607f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Accessmode, 1 } } },
608f44fc79dSJohn Baldwin 	{ .name = "linux_execve", .ret_type = 1, .nargs = 3,
609f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
610f44fc79dSJohn Baldwin 		    { ExecEnv | IN, 2 } } },
611*b9b86b67SDmitry Chagin 	{ .name = "linux_getitimer", .ret_type = 1, .nargs = 2,
612*b9b86b67SDmitry Chagin 	  .args = { { Itimerwhich, 0 }, { Itimerval | OUT, 2 } } },
613f44fc79dSJohn Baldwin 	{ .name = "linux_lseek", .ret_type = 2, .nargs = 3,
614f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } },
615f44fc79dSJohn Baldwin 	{ .name = "linux_mkdir", .ret_type = 1, .nargs = 2,
616f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Int, 1 } } },
617f44fc79dSJohn Baldwin 	{ .name = "linux_newfstat", .ret_type = 1, .nargs = 2,
618f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { Ptr | OUT, 1 } } },
619f44fc79dSJohn Baldwin 	{ .name = "linux_newstat", .ret_type = 1, .nargs = 2,
620f44fc79dSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
621f44fc79dSJohn Baldwin 	{ .name = "linux_open", .ret_type = 1, .nargs = 3,
622f44fc79dSJohn Baldwin 	  .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } },
623f44fc79dSJohn Baldwin 	{ .name = "linux_readlink", .ret_type = 1, .nargs = 3,
624e261fb2aSJohn Baldwin 	  .args = { { Name, 0 }, { Name | OUT, 1 }, { Sizet, 2 } } },
625*b9b86b67SDmitry Chagin 	{ .name = "linux_setitimer", .ret_type = 1, .nargs = 3,
626*b9b86b67SDmitry Chagin 	  .args = { { Itimerwhich, 0 }, { Itimerval, 1 },
627*b9b86b67SDmitry Chagin 		    { Itimerval | OUT, 2 } } },
628f44fc79dSJohn Baldwin 	{ .name = "linux_socketcall", .ret_type = 1, .nargs = 2,
629f44fc79dSJohn Baldwin 	  .args = { { Int, 0 }, { LinuxSockArgs, 1 } } },
63064f4703bSJohn Baldwin 	{ .name = "linux_stat64", .ret_type = 1, .nargs = 2,
63164f4703bSJohn Baldwin 	  .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
632bbeaf6c0SSean Eric Fagan };
6336019514bSAlex Richardson static STAILQ_HEAD(, syscall) seen_syscalls;
634bbeaf6c0SSean Eric Fagan 
635081e5c48SPav Lucistnik /* Xlat idea taken from strace */
636081e5c48SPav Lucistnik struct xlat {
637081e5c48SPav Lucistnik 	int val;
6385d2d083cSXin LI 	const char *str;
639081e5c48SPav Lucistnik };
640081e5c48SPav Lucistnik 
641081e5c48SPav Lucistnik #define	X(a)	{ a, #a },
642081e5c48SPav Lucistnik #define	XEND	{ 0, NULL }
643081e5c48SPav Lucistnik 
644a02c83afSEd Schouten static struct xlat poll_flags[] = {
645081e5c48SPav Lucistnik 	X(POLLSTANDARD) X(POLLIN) X(POLLPRI) X(POLLOUT) X(POLLERR)
646081e5c48SPav Lucistnik 	X(POLLHUP) X(POLLNVAL) X(POLLRDNORM) X(POLLRDBAND)
6473aaaa2efSThomas Munro 	X(POLLWRBAND) X(POLLINIGNEOF) X(POLLRDHUP) XEND
648081e5c48SPav Lucistnik };
649081e5c48SPav Lucistnik 
650081e5c48SPav Lucistnik static struct xlat sigaction_flags[] = {
651081e5c48SPav Lucistnik 	X(SA_ONSTACK) X(SA_RESTART) X(SA_RESETHAND) X(SA_NOCLDSTOP)
652081e5c48SPav Lucistnik 	X(SA_NODEFER) X(SA_NOCLDWAIT) X(SA_SIGINFO) XEND
653081e5c48SPav Lucistnik };
654081e5c48SPav Lucistnik 
655fb7eabb0SJohn Baldwin static struct xlat linux_socketcall_ops[] = {
656fb7eabb0SJohn Baldwin 	X(LINUX_SOCKET) X(LINUX_BIND) X(LINUX_CONNECT) X(LINUX_LISTEN)
657fb7eabb0SJohn Baldwin 	X(LINUX_ACCEPT) X(LINUX_GETSOCKNAME) X(LINUX_GETPEERNAME)
658fb7eabb0SJohn Baldwin 	X(LINUX_SOCKETPAIR) X(LINUX_SEND) X(LINUX_RECV) X(LINUX_SENDTO)
659fb7eabb0SJohn Baldwin 	X(LINUX_RECVFROM) X(LINUX_SHUTDOWN) X(LINUX_SETSOCKOPT)
660fb7eabb0SJohn Baldwin 	X(LINUX_GETSOCKOPT) X(LINUX_SENDMSG) X(LINUX_RECVMSG)
661fb7eabb0SJohn Baldwin 	XEND
662fb7eabb0SJohn Baldwin };
663fb7eabb0SJohn Baldwin 
664bb24ee2bSThomas Munro static struct xlat lio_modes[] = {
665bb24ee2bSThomas Munro 	X(LIO_WAIT) X(LIO_NOWAIT)
666bb24ee2bSThomas Munro 	XEND
667bb24ee2bSThomas Munro };
668bb24ee2bSThomas Munro 
669bb24ee2bSThomas Munro static struct xlat lio_opcodes[] = {
670f30a1ae8SThomas Munro 	X(LIO_WRITE) X(LIO_READ) X(LIO_READV) X(LIO_WRITEV) X(LIO_NOP)
671bb24ee2bSThomas Munro 	XEND
672bb24ee2bSThomas Munro };
673bb24ee2bSThomas Munro 
674bb24ee2bSThomas Munro static struct xlat aio_fsync_ops[] = {
675bb24ee2bSThomas Munro 	X(O_SYNC)
676bb24ee2bSThomas Munro 	XEND
677bb24ee2bSThomas Munro };
678bb24ee2bSThomas Munro 
679081e5c48SPav Lucistnik #undef X
680081e5c48SPav Lucistnik #undef XEND
681081e5c48SPav Lucistnik 
682d8984f48SDag-Erling Smørgrav /*
683d8984f48SDag-Erling Smørgrav  * Searches an xlat array for a value, and returns it if found.  Otherwise
684d8984f48SDag-Erling Smørgrav  * return a string representation.
685d8984f48SDag-Erling Smørgrav  */
686d8984f48SDag-Erling Smørgrav static const char *
687d8984f48SDag-Erling Smørgrav lookup(struct xlat *xlat, int val, int base)
688081e5c48SPav Lucistnik {
689081e5c48SPav Lucistnik 	static char tmp[16];
690d8984f48SDag-Erling Smørgrav 
691081e5c48SPav Lucistnik 	for (; xlat->str != NULL; xlat++)
692081e5c48SPav Lucistnik 		if (xlat->val == val)
693d8984f48SDag-Erling Smørgrav 			return (xlat->str);
694081e5c48SPav Lucistnik 	switch (base) {
695081e5c48SPav Lucistnik 	case 8:
696081e5c48SPav Lucistnik 		sprintf(tmp, "0%o", val);
697081e5c48SPav Lucistnik 		break;
698081e5c48SPav Lucistnik 	case 16:
699081e5c48SPav Lucistnik 		sprintf(tmp, "0x%x", val);
700081e5c48SPav Lucistnik 		break;
701081e5c48SPav Lucistnik 	case 10:
702081e5c48SPav Lucistnik 		sprintf(tmp, "%u", val);
703081e5c48SPav Lucistnik 		break;
704081e5c48SPav Lucistnik 	default:
705081e5c48SPav Lucistnik 		errx(1, "Unknown lookup base");
706081e5c48SPav Lucistnik 	}
707d8984f48SDag-Erling Smørgrav 	return (tmp);
708081e5c48SPav Lucistnik }
709081e5c48SPav Lucistnik 
7105d2d083cSXin LI static const char *
7115d2d083cSXin LI xlookup(struct xlat *xlat, int val)
712081e5c48SPav Lucistnik {
713d8984f48SDag-Erling Smørgrav 
714d8984f48SDag-Erling Smørgrav 	return (lookup(xlat, val, 16));
715081e5c48SPav Lucistnik }
716081e5c48SPav Lucistnik 
7174e3da534SJohn Baldwin /*
7184e3da534SJohn Baldwin  * Searches an xlat array containing bitfield values.  Remaining bits
7194e3da534SJohn Baldwin  * set after removing the known ones are printed at the end:
7204e3da534SJohn Baldwin  * IN|0x400.
7214e3da534SJohn Baldwin  */
722d8984f48SDag-Erling Smørgrav static char *
723d8984f48SDag-Erling Smørgrav xlookup_bits(struct xlat *xlat, int val)
724081e5c48SPav Lucistnik {
72594355cfdSAndrey Zonov 	int len, rem;
726081e5c48SPav Lucistnik 	static char str[512];
727081e5c48SPav Lucistnik 
72894355cfdSAndrey Zonov 	len = 0;
72994355cfdSAndrey Zonov 	rem = val;
730d8984f48SDag-Erling Smørgrav 	for (; xlat->str != NULL; xlat++) {
731d8984f48SDag-Erling Smørgrav 		if ((xlat->val & rem) == xlat->val) {
7324e3da534SJohn Baldwin 			/*
7334e3da534SJohn Baldwin 			 * Don't print the "all-bits-zero" string unless all
7344e3da534SJohn Baldwin 			 * bits are really zero.
7354e3da534SJohn Baldwin 			 */
736081e5c48SPav Lucistnik 			if (xlat->val == 0 && val != 0)
737081e5c48SPav Lucistnik 				continue;
738081e5c48SPav Lucistnik 			len += sprintf(str + len, "%s|", xlat->str);
739081e5c48SPav Lucistnik 			rem &= ~(xlat->val);
740081e5c48SPav Lucistnik 		}
741081e5c48SPav Lucistnik 	}
7424e3da534SJohn Baldwin 
7434e3da534SJohn Baldwin 	/*
7444e3da534SJohn Baldwin 	 * If we have leftover bits or didn't match anything, print
7454e3da534SJohn Baldwin 	 * the remainder.
7464e3da534SJohn Baldwin 	 */
747081e5c48SPav Lucistnik 	if (rem || len == 0)
748081e5c48SPav Lucistnik 		len += sprintf(str + len, "0x%x", rem);
749081e5c48SPav Lucistnik 	if (len && str[len - 1] == '|')
750081e5c48SPav Lucistnik 		len--;
751081e5c48SPav Lucistnik 	str[len] = 0;
752d8984f48SDag-Erling Smørgrav 	return (str);
753081e5c48SPav Lucistnik }
754081e5c48SPav Lucistnik 
7559289f547SJohn Baldwin static void
7569289f547SJohn Baldwin print_integer_arg(const char *(*decoder)(int), FILE *fp, int value)
7579289f547SJohn Baldwin {
7589289f547SJohn Baldwin 	const char *str;
7599289f547SJohn Baldwin 
7609289f547SJohn Baldwin 	str = decoder(value);
7619289f547SJohn Baldwin 	if (str != NULL)
7629289f547SJohn Baldwin 		fputs(str, fp);
7639289f547SJohn Baldwin 	else
7649289f547SJohn Baldwin 		fprintf(fp, "%d", value);
7659289f547SJohn Baldwin }
7669289f547SJohn Baldwin 
767c2679dd7SKyle Evans static bool
768c2679dd7SKyle Evans print_mask_arg_part(bool (*decoder)(FILE *, int, int *), FILE *fp, int value,
769c2679dd7SKyle Evans     int *rem)
770c2679dd7SKyle Evans {
771c2679dd7SKyle Evans 
772c2679dd7SKyle Evans 	return (decoder(fp, value, rem));
773c2679dd7SKyle Evans }
774c2679dd7SKyle Evans 
7759289f547SJohn Baldwin static void
7769289f547SJohn Baldwin print_mask_arg(bool (*decoder)(FILE *, int, int *), FILE *fp, int value)
7779289f547SJohn Baldwin {
7789289f547SJohn Baldwin 	int rem;
7799289f547SJohn Baldwin 
780c2679dd7SKyle Evans 	if (!print_mask_arg_part(decoder, fp, value, &rem))
7819289f547SJohn Baldwin 		fprintf(fp, "0x%x", rem);
7829289f547SJohn Baldwin 	else if (rem != 0)
7839289f547SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
7849289f547SJohn Baldwin }
7859289f547SJohn Baldwin 
786bed418c8SJohn Baldwin static void
787bed418c8SJohn Baldwin print_mask_arg32(bool (*decoder)(FILE *, uint32_t, uint32_t *), FILE *fp,
788bed418c8SJohn Baldwin     uint32_t value)
789bed418c8SJohn Baldwin {
790bed418c8SJohn Baldwin 	uint32_t rem;
791bed418c8SJohn Baldwin 
792bed418c8SJohn Baldwin 	if (!decoder(fp, value, &rem))
793bed418c8SJohn Baldwin 		fprintf(fp, "0x%x", rem);
794bed418c8SJohn Baldwin 	else if (rem != 0)
795bed418c8SJohn Baldwin 		fprintf(fp, "|0x%x", rem);
796bed418c8SJohn Baldwin }
797bed418c8SJohn Baldwin 
798c05cc0d6SJohn Baldwin /*
799214b7670SJohn Baldwin  * Add argument padding to subsequent system calls after Quad
800c05cc0d6SJohn Baldwin  * syscall arguments as needed.  This used to be done by hand in the
801c05cc0d6SJohn Baldwin  * decoded_syscalls table which was ugly and error prone.  It is
8025aa0576bSEd Maste  * simpler to do the fixup of offsets at initialization time than when
803c05cc0d6SJohn Baldwin  * decoding arguments.
804c05cc0d6SJohn Baldwin  */
805c05cc0d6SJohn Baldwin static void
806f4b7018aSOlivier Houchard quad_fixup(struct syscall_decode *sc)
807c05cc0d6SJohn Baldwin {
808c05cc0d6SJohn Baldwin 	int offset, prev;
809c05cc0d6SJohn Baldwin 	u_int i;
810c05cc0d6SJohn Baldwin 
811c05cc0d6SJohn Baldwin 	offset = 0;
812c05cc0d6SJohn Baldwin 	prev = -1;
813c05cc0d6SJohn Baldwin 	for (i = 0; i < sc->nargs; i++) {
814c05cc0d6SJohn Baldwin 		/* This arg type is a dummy that doesn't use offset. */
815c05cc0d6SJohn Baldwin 		if ((sc->args[i].type & ARG_MASK) == PipeFds)
816c05cc0d6SJohn Baldwin 			continue;
817c05cc0d6SJohn Baldwin 
818c05cc0d6SJohn Baldwin 		assert(prev < sc->args[i].offset);
819c05cc0d6SJohn Baldwin 		prev = sc->args[i].offset;
820c05cc0d6SJohn Baldwin 		sc->args[i].offset += offset;
821c05cc0d6SJohn Baldwin 		switch (sc->args[i].type & ARG_MASK) {
822c05cc0d6SJohn Baldwin 		case Quad:
823c05cc0d6SJohn Baldwin 		case QuadHex:
824ebbc3140SOlivier Houchard #if defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
825c05cc0d6SJohn Baldwin 			/*
826ebbc3140SOlivier Houchard 			 * 64-bit arguments on 32-bit powerpc and arm must be
827c05cc0d6SJohn Baldwin 			 * 64-bit aligned.  If the current offset is
828c05cc0d6SJohn Baldwin 			 * not aligned, the calling convention inserts
829c05cc0d6SJohn Baldwin 			 * a 32-bit pad argument that should be skipped.
830c05cc0d6SJohn Baldwin 			 */
831c05cc0d6SJohn Baldwin 			if (sc->args[i].offset % 2 == 1) {
832c05cc0d6SJohn Baldwin 				sc->args[i].offset++;
833c05cc0d6SJohn Baldwin 				offset++;
834c05cc0d6SJohn Baldwin 			}
835c05cc0d6SJohn Baldwin #endif
836c05cc0d6SJohn Baldwin 			offset++;
837c05cc0d6SJohn Baldwin 		default:
838c05cc0d6SJohn Baldwin 			break;
839c05cc0d6SJohn Baldwin 		}
840c05cc0d6SJohn Baldwin 	}
841c05cc0d6SJohn Baldwin }
842c05cc0d6SJohn Baldwin 
8431175b23fSJohn Baldwin static struct syscall *
8441175b23fSJohn Baldwin find_syscall(struct procabi *abi, u_int number)
8451175b23fSJohn Baldwin {
8461175b23fSJohn Baldwin 	struct extra_syscall *es;
8471175b23fSJohn Baldwin 
8481175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls))
8491175b23fSJohn Baldwin 		return (abi->syscalls[number]);
8501175b23fSJohn Baldwin 	STAILQ_FOREACH(es, &abi->extra_syscalls, entries) {
8511175b23fSJohn Baldwin 		if (es->number == number)
8521175b23fSJohn Baldwin 			return (es->sc);
8531175b23fSJohn Baldwin 	}
8541175b23fSJohn Baldwin 	return (NULL);
8551175b23fSJohn Baldwin }
8561175b23fSJohn Baldwin 
8571175b23fSJohn Baldwin static void
8581175b23fSJohn Baldwin add_syscall(struct procabi *abi, u_int number, struct syscall *sc)
8591175b23fSJohn Baldwin {
8601175b23fSJohn Baldwin 	struct extra_syscall *es;
8611175b23fSJohn Baldwin 
8627daca4e2SAlex Richardson 	/*
8637daca4e2SAlex Richardson 	 * quad_fixup() is currently needed for all 32-bit ABIs.
8647daca4e2SAlex Richardson 	 * TODO: This should probably be a function pointer inside struct
8657daca4e2SAlex Richardson 	 *  procabi instead.
8667daca4e2SAlex Richardson 	 */
8677daca4e2SAlex Richardson 	if (abi->pointer_size == 4)
868f4b7018aSOlivier Houchard 		quad_fixup(&sc->decode);
8696019514bSAlex Richardson 
8701175b23fSJohn Baldwin 	if (number < nitems(abi->syscalls)) {
8711175b23fSJohn Baldwin 		assert(abi->syscalls[number] == NULL);
8721175b23fSJohn Baldwin 		abi->syscalls[number] = sc;
8731175b23fSJohn Baldwin 	} else {
8741175b23fSJohn Baldwin 		es = malloc(sizeof(*es));
8751175b23fSJohn Baldwin 		es->sc = sc;
8761175b23fSJohn Baldwin 		es->number = number;
8771175b23fSJohn Baldwin 		STAILQ_INSERT_TAIL(&abi->extra_syscalls, es, entries);
8781175b23fSJohn Baldwin 	}
8796019514bSAlex Richardson 
8806019514bSAlex Richardson 	STAILQ_INSERT_HEAD(&seen_syscalls, sc, entries);
8811175b23fSJohn Baldwin }
8821175b23fSJohn Baldwin 
883bbeaf6c0SSean Eric Fagan /*
884bbeaf6c0SSean Eric Fagan  * If/when the list gets big, it might be desirable to do it
885bbeaf6c0SSean Eric Fagan  * as a hash table or binary search.
886bbeaf6c0SSean Eric Fagan  */
887bbeaf6c0SSean Eric Fagan struct syscall *
8881175b23fSJohn Baldwin get_syscall(struct threadinfo *t, u_int number, u_int nargs)
889d8984f48SDag-Erling Smørgrav {
89094355cfdSAndrey Zonov 	struct syscall *sc;
8917daca4e2SAlex Richardson 	struct procabi *procabi;
8926019514bSAlex Richardson 	const char *sysdecode_name;
8937daca4e2SAlex Richardson 	const char *lookup_name;
8941175b23fSJohn Baldwin 	const char *name;
8951175b23fSJohn Baldwin 	u_int i;
896bbeaf6c0SSean Eric Fagan 
8977daca4e2SAlex Richardson 	procabi = t->proc->abi;
8987daca4e2SAlex Richardson 	sc = find_syscall(procabi, number);
8991175b23fSJohn Baldwin 	if (sc != NULL)
900d8984f48SDag-Erling Smørgrav 		return (sc);
9016c61b0f3SBryan Drewery 
9026019514bSAlex Richardson 	/* Memory is not explicitly deallocated, it's released on exit(). */
9037daca4e2SAlex Richardson 	sysdecode_name = sysdecode_syscallname(procabi->abi, number);
9046019514bSAlex Richardson 	if (sysdecode_name == NULL)
9056019514bSAlex Richardson 		asprintf(__DECONST(char **, &name), "#%d", number);
9066019514bSAlex Richardson 	else
9076019514bSAlex Richardson 		name = sysdecode_name;
9086019514bSAlex Richardson 
9096019514bSAlex Richardson 	sc = calloc(1, sizeof(*sc));
9106019514bSAlex Richardson 	sc->name = name;
9116019514bSAlex Richardson 
9127daca4e2SAlex Richardson 	/* Also decode compat syscalls arguments by stripping the prefix. */
9137daca4e2SAlex Richardson 	lookup_name = name;
9147daca4e2SAlex Richardson 	if (procabi->compat_prefix != NULL && strncmp(procabi->compat_prefix,
9157daca4e2SAlex Richardson 	    name, strlen(procabi->compat_prefix)) == 0)
9167daca4e2SAlex Richardson 		lookup_name += strlen(procabi->compat_prefix);
9177daca4e2SAlex Richardson 
9186019514bSAlex Richardson 	for (i = 0; i < nitems(decoded_syscalls); i++) {
9197daca4e2SAlex Richardson 		if (strcmp(lookup_name, decoded_syscalls[i].name) == 0) {
9206019514bSAlex Richardson 			sc->decode = decoded_syscalls[i];
9211175b23fSJohn Baldwin 			add_syscall(t->proc->abi, number, sc);
9221175b23fSJohn Baldwin 			return (sc);
9231175b23fSJohn Baldwin 		}
9241175b23fSJohn Baldwin 	}
9251175b23fSJohn Baldwin 
9266c61b0f3SBryan Drewery 	/* It is unknown.  Add it into the list. */
9276c61b0f3SBryan Drewery #if DEBUG
9286c61b0f3SBryan Drewery 	fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
9296c61b0f3SBryan Drewery 	    nargs);
9306c61b0f3SBryan Drewery #endif
9316019514bSAlex Richardson 	sc->unknown = sysdecode_name == NULL;
9326019514bSAlex Richardson 	sc->decode.ret_type = 1; /* Assume 1 return value. */
9336019514bSAlex Richardson 	sc->decode.nargs = nargs;
9346c61b0f3SBryan Drewery 	for (i = 0; i < nargs; i++) {
9356019514bSAlex Richardson 		sc->decode.args[i].offset = i;
9366c61b0f3SBryan Drewery 		/* Treat all unknown arguments as LongHex. */
9376019514bSAlex Richardson 		sc->decode.args[i].type = LongHex;
938bbeaf6c0SSean Eric Fagan 	}
9391175b23fSJohn Baldwin 	add_syscall(t->proc->abi, number, sc);
9406c61b0f3SBryan Drewery 	return (sc);
941bbeaf6c0SSean Eric Fagan }
942bbeaf6c0SSean Eric Fagan 
943bbeaf6c0SSean Eric Fagan /*
9449ddd1412SDag-Erling Smørgrav  * Copy a fixed amount of bytes from the process.
9459ddd1412SDag-Erling Smørgrav  */
9461be5d704SMark Murray static int
94731dddc6aSAlex Richardson get_struct(pid_t pid, psaddr_t offset, void *buf, size_t len)
948d8984f48SDag-Erling Smørgrav {
9495d2d083cSXin LI 	struct ptrace_io_desc iorequest;
9509ddd1412SDag-Erling Smørgrav 
9515d2d083cSXin LI 	iorequest.piod_op = PIOD_READ_D;
95231dddc6aSAlex Richardson 	iorequest.piod_offs = (void *)(uintptr_t)offset;
9535d2d083cSXin LI 	iorequest.piod_addr = buf;
9545d2d083cSXin LI 	iorequest.piod_len = len;
9555d2d083cSXin LI 	if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0)
956d8984f48SDag-Erling Smørgrav 		return (-1);
957d8984f48SDag-Erling Smørgrav 	return (0);
9589ddd1412SDag-Erling Smørgrav }
9599ddd1412SDag-Erling Smørgrav 
9605d2d083cSXin LI #define	MAXSIZE		4096
961abb3f965SJohn Baldwin 
9629ddd1412SDag-Erling Smørgrav /*
963bbeaf6c0SSean Eric Fagan  * Copy a string from the process.  Note that it is
964bbeaf6c0SSean Eric Fagan  * expected to be a C string, but if max is set, it will
965bbeaf6c0SSean Eric Fagan  * only get that much.
966bbeaf6c0SSean Eric Fagan  */
9675d2d083cSXin LI static char *
96831dddc6aSAlex Richardson get_string(pid_t pid, psaddr_t addr, int max)
969d8984f48SDag-Erling Smørgrav {
9705d2d083cSXin LI 	struct ptrace_io_desc iorequest;
971abb3f965SJohn Baldwin 	char *buf, *nbuf;
972abb3f965SJohn Baldwin 	size_t offset, size, totalsize;
973bbeaf6c0SSean Eric Fagan 
974abb3f965SJohn Baldwin 	offset = 0;
975abb3f965SJohn Baldwin 	if (max)
976abb3f965SJohn Baldwin 		size = max + 1;
977abb3f965SJohn Baldwin 	else {
978abb3f965SJohn Baldwin 		/* Read up to the end of the current page. */
97931dddc6aSAlex Richardson 		size = PAGE_SIZE - (addr % PAGE_SIZE);
980abb3f965SJohn Baldwin 		if (size > MAXSIZE)
981abb3f965SJohn Baldwin 			size = MAXSIZE;
982abb3f965SJohn Baldwin 	}
983abb3f965SJohn Baldwin 	totalsize = size;
9845d2d083cSXin LI 	buf = malloc(totalsize);
9855d2d083cSXin LI 	if (buf == NULL)
986d8984f48SDag-Erling Smørgrav 		return (NULL);
9875d2d083cSXin LI 	for (;;) {
9885d2d083cSXin LI 		iorequest.piod_op = PIOD_READ_D;
98931dddc6aSAlex Richardson 		iorequest.piod_offs = (void *)((uintptr_t)addr + offset);
990abb3f965SJohn Baldwin 		iorequest.piod_addr = buf + offset;
9915d2d083cSXin LI 		iorequest.piod_len = size;
9925d2d083cSXin LI 		if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) {
9935d2d083cSXin LI 			free(buf);
994d8984f48SDag-Erling Smørgrav 			return (NULL);
995bbeaf6c0SSean Eric Fagan 		}
996abb3f965SJohn Baldwin 		if (memchr(buf + offset, '\0', size) != NULL)
997abb3f965SJohn Baldwin 			return (buf);
998abb3f965SJohn Baldwin 		offset += size;
999abb3f965SJohn Baldwin 		if (totalsize < MAXSIZE && max == 0) {
1000abb3f965SJohn Baldwin 			size = MAXSIZE - totalsize;
1001abb3f965SJohn Baldwin 			if (size > PAGE_SIZE)
1002abb3f965SJohn Baldwin 				size = PAGE_SIZE;
1003abb3f965SJohn Baldwin 			nbuf = realloc(buf, totalsize + size);
1004abb3f965SJohn Baldwin 			if (nbuf == NULL) {
1005abb3f965SJohn Baldwin 				buf[totalsize - 1] = '\0';
10064e92419dSMarcel Moolenaar 				return (buf);
1007bbeaf6c0SSean Eric Fagan 			}
1008abb3f965SJohn Baldwin 			buf = nbuf;
1009abb3f965SJohn Baldwin 			totalsize += size;
1010d8984f48SDag-Erling Smørgrav 		} else {
1011cdfc719cSJaakko Heinonen 			buf[totalsize - 1] = '\0';
1012d8984f48SDag-Erling Smørgrav 			return (buf);
10135d2d083cSXin LI 		}
10145d2d083cSXin LI 	}
10155d2d083cSXin LI }
1016bbeaf6c0SSean Eric Fagan 
10179289f547SJohn Baldwin static const char *
101834763d1cSJohn Baldwin strsig2(int sig)
101934763d1cSJohn Baldwin {
10209289f547SJohn Baldwin 	static char tmp[32];
10219289f547SJohn Baldwin 	const char *signame;
102234763d1cSJohn Baldwin 
10239289f547SJohn Baldwin 	signame = sysdecode_signal(sig);
10249289f547SJohn Baldwin 	if (signame == NULL) {
1025f083f689SJohn Baldwin 		snprintf(tmp, sizeof(tmp), "%d", sig);
10269289f547SJohn Baldwin 		signame = tmp;
1027f083f689SJohn Baldwin 	}
10289289f547SJohn Baldwin 	return (signame);
102934763d1cSJohn Baldwin }
1030bbeaf6c0SSean Eric Fagan 
1031c915ff03SJohn Baldwin static void
1032ffb66079SJohn Baldwin print_kevent(FILE *fp, struct kevent *ke)
1033c915ff03SJohn Baldwin {
1034c915ff03SJohn Baldwin 
1035c915ff03SJohn Baldwin 	switch (ke->filter) {
1036c915ff03SJohn Baldwin 	case EVFILT_READ:
1037c915ff03SJohn Baldwin 	case EVFILT_WRITE:
1038c915ff03SJohn Baldwin 	case EVFILT_VNODE:
1039c915ff03SJohn Baldwin 	case EVFILT_PROC:
1040c915ff03SJohn Baldwin 	case EVFILT_TIMER:
1041c915ff03SJohn Baldwin 	case EVFILT_PROCDESC:
1042ffb66079SJohn Baldwin 	case EVFILT_EMPTY:
1043c915ff03SJohn Baldwin 		fprintf(fp, "%ju", (uintmax_t)ke->ident);
1044c915ff03SJohn Baldwin 		break;
1045c915ff03SJohn Baldwin 	case EVFILT_SIGNAL:
1046c915ff03SJohn Baldwin 		fputs(strsig2(ke->ident), fp);
1047c915ff03SJohn Baldwin 		break;
1048c915ff03SJohn Baldwin 	default:
1049c915ff03SJohn Baldwin 		fprintf(fp, "%p", (void *)ke->ident);
1050c915ff03SJohn Baldwin 	}
1051ffb66079SJohn Baldwin 	fprintf(fp, ",");
1052ffb66079SJohn Baldwin 	print_integer_arg(sysdecode_kevent_filter, fp, ke->filter);
1053ffb66079SJohn Baldwin 	fprintf(fp, ",");
1054ffb66079SJohn Baldwin 	print_mask_arg(sysdecode_kevent_flags, fp, ke->flags);
1055ffb66079SJohn Baldwin 	fprintf(fp, ",");
1056ffb66079SJohn Baldwin 	sysdecode_kevent_fflags(fp, ke->filter, ke->fflags, 16);
10572b34e843SKonstantin Belousov 	fprintf(fp, ",%#jx,%p", (uintmax_t)ke->data, ke->udata);
1058c915ff03SJohn Baldwin }
1059c915ff03SJohn Baldwin 
1060195aef99SBryan Drewery static void
1061195aef99SBryan Drewery print_utrace(FILE *fp, void *utrace_addr, size_t len)
1062195aef99SBryan Drewery {
1063195aef99SBryan Drewery 	unsigned char *utrace_buffer;
1064195aef99SBryan Drewery 
1065195aef99SBryan Drewery 	fprintf(fp, "{ ");
1066d6fb4894SJohn Baldwin 	if (sysdecode_utrace(fp, utrace_addr, len)) {
1067195aef99SBryan Drewery 		fprintf(fp, " }");
1068195aef99SBryan Drewery 		return;
1069195aef99SBryan Drewery 	}
1070195aef99SBryan Drewery 
1071195aef99SBryan Drewery 	utrace_buffer = utrace_addr;
1072195aef99SBryan Drewery 	fprintf(fp, "%zu:", len);
1073195aef99SBryan Drewery 	while (len--)
1074195aef99SBryan Drewery 		fprintf(fp, " %02x", *utrace_buffer++);
1075195aef99SBryan Drewery 	fprintf(fp, " }");
1076195aef99SBryan Drewery }
1077195aef99SBryan Drewery 
1078a2674e03SMichael Tuexen static void
1079cc86d14aSBrooks Davis print_pointer(FILE *fp, uintptr_t arg)
1080cc86d14aSBrooks Davis {
1081cc86d14aSBrooks Davis 
1082cc86d14aSBrooks Davis 	fprintf(fp, "%p", (void *)arg);
1083cc86d14aSBrooks Davis }
1084cc86d14aSBrooks Davis 
1085cc86d14aSBrooks Davis static void
1086cc86d14aSBrooks Davis print_sockaddr(FILE *fp, struct trussinfo *trussinfo, uintptr_t arg,
1087cc86d14aSBrooks Davis     socklen_t len)
1088a2674e03SMichael Tuexen {
1089a2674e03SMichael Tuexen 	char addr[64];
1090a2674e03SMichael Tuexen 	struct sockaddr_in *lsin;
1091a2674e03SMichael Tuexen 	struct sockaddr_in6 *lsin6;
1092a2674e03SMichael Tuexen 	struct sockaddr_un *sun;
1093a2674e03SMichael Tuexen 	struct sockaddr *sa;
1094a2674e03SMichael Tuexen 	u_char *q;
1095a2674e03SMichael Tuexen 	pid_t pid = trussinfo->curthread->proc->pid;
1096a2674e03SMichael Tuexen 
1097cc86d14aSBrooks Davis 	if (arg == 0) {
1098a2674e03SMichael Tuexen 		fputs("NULL", fp);
1099a2674e03SMichael Tuexen 		return;
1100a2674e03SMichael Tuexen 	}
1101a2674e03SMichael Tuexen 	/* If the length is too small, just bail. */
1102a2674e03SMichael Tuexen 	if (len < sizeof(*sa)) {
1103cc86d14aSBrooks Davis 		print_pointer(fp, arg);
1104a2674e03SMichael Tuexen 		return;
1105a2674e03SMichael Tuexen 	}
1106a2674e03SMichael Tuexen 
1107a2674e03SMichael Tuexen 	sa = calloc(1, len);
1108a2674e03SMichael Tuexen 	if (get_struct(pid, arg, sa, len) == -1) {
1109a2674e03SMichael Tuexen 		free(sa);
1110cc86d14aSBrooks Davis 		print_pointer(fp, arg);
1111a2674e03SMichael Tuexen 		return;
1112a2674e03SMichael Tuexen 	}
1113a2674e03SMichael Tuexen 
1114a2674e03SMichael Tuexen 	switch (sa->sa_family) {
1115a2674e03SMichael Tuexen 	case AF_INET:
1116a2674e03SMichael Tuexen 		if (len < sizeof(*lsin))
1117a2674e03SMichael Tuexen 			goto sockaddr_short;
1118a2674e03SMichael Tuexen 		lsin = (struct sockaddr_in *)(void *)sa;
1119a2674e03SMichael Tuexen 		inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr));
1120a2674e03SMichael Tuexen 		fprintf(fp, "{ AF_INET %s:%d }", addr,
1121a2674e03SMichael Tuexen 		    htons(lsin->sin_port));
1122a2674e03SMichael Tuexen 		break;
1123a2674e03SMichael Tuexen 	case AF_INET6:
1124a2674e03SMichael Tuexen 		if (len < sizeof(*lsin6))
1125a2674e03SMichael Tuexen 			goto sockaddr_short;
1126a2674e03SMichael Tuexen 		lsin6 = (struct sockaddr_in6 *)(void *)sa;
1127a2674e03SMichael Tuexen 		inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
1128a2674e03SMichael Tuexen 		    sizeof(addr));
1129a2674e03SMichael Tuexen 		fprintf(fp, "{ AF_INET6 [%s]:%d }", addr,
1130a2674e03SMichael Tuexen 		    htons(lsin6->sin6_port));
1131a2674e03SMichael Tuexen 		break;
1132a2674e03SMichael Tuexen 	case AF_UNIX:
1133a2674e03SMichael Tuexen 		sun = (struct sockaddr_un *)sa;
1134a2674e03SMichael Tuexen 		fprintf(fp, "{ AF_UNIX \"%.*s\" }",
1135a2674e03SMichael Tuexen 		    (int)(len - offsetof(struct sockaddr_un, sun_path)),
1136a2674e03SMichael Tuexen 		    sun->sun_path);
1137a2674e03SMichael Tuexen 		break;
1138a2674e03SMichael Tuexen 	default:
1139a2674e03SMichael Tuexen 	sockaddr_short:
1140a2674e03SMichael Tuexen 		fprintf(fp,
1141a2674e03SMichael Tuexen 		    "{ sa_len = %d, sa_family = %d, sa_data = {",
1142a2674e03SMichael Tuexen 		    (int)sa->sa_len, (int)sa->sa_family);
1143a2674e03SMichael Tuexen 		for (q = (u_char *)sa->sa_data;
1144a2674e03SMichael Tuexen 		     q < (u_char *)sa + len; q++)
1145a2674e03SMichael Tuexen 			fprintf(fp, "%s 0x%02x",
1146a2674e03SMichael Tuexen 			    q == (u_char *)sa->sa_data ? "" : ",",
1147a2674e03SMichael Tuexen 			    *q);
1148a2674e03SMichael Tuexen 		fputs(" } }", fp);
1149a2674e03SMichael Tuexen 	}
1150a2674e03SMichael Tuexen 	free(sa);
1151a2674e03SMichael Tuexen }
1152a2674e03SMichael Tuexen 
1153a2674e03SMichael Tuexen #define IOV_LIMIT 16
1154a2674e03SMichael Tuexen 
1155a2674e03SMichael Tuexen static void
1156cc86d14aSBrooks Davis print_iovec(FILE *fp, struct trussinfo *trussinfo, uintptr_t arg, int iovcnt)
1157a2674e03SMichael Tuexen {
1158a2674e03SMichael Tuexen 	struct iovec iov[IOV_LIMIT];
1159a2674e03SMichael Tuexen 	size_t max_string = trussinfo->strsize;
1160a2674e03SMichael Tuexen 	char tmp2[max_string + 1], *tmp3;
1161a2674e03SMichael Tuexen 	size_t len;
1162a2674e03SMichael Tuexen 	pid_t pid = trussinfo->curthread->proc->pid;
1163a2674e03SMichael Tuexen 	int i;
1164a2674e03SMichael Tuexen 	bool buf_truncated, iov_truncated;
1165a2674e03SMichael Tuexen 
1166a2674e03SMichael Tuexen 	if (iovcnt <= 0) {
1167cc86d14aSBrooks Davis 		print_pointer(fp, arg);
1168a2674e03SMichael Tuexen 		return;
1169a2674e03SMichael Tuexen 	}
1170a2674e03SMichael Tuexen 	if (iovcnt > IOV_LIMIT) {
1171a2674e03SMichael Tuexen 		iovcnt = IOV_LIMIT;
1172a2674e03SMichael Tuexen 		iov_truncated = true;
1173a2674e03SMichael Tuexen 	} else {
1174a2674e03SMichael Tuexen 		iov_truncated = false;
1175a2674e03SMichael Tuexen 	}
1176a2674e03SMichael Tuexen 	if (get_struct(pid, arg, &iov, iovcnt * sizeof(struct iovec)) == -1) {
1177cc86d14aSBrooks Davis 		print_pointer(fp, arg);
1178a2674e03SMichael Tuexen 		return;
1179a2674e03SMichael Tuexen 	}
1180a2674e03SMichael Tuexen 
1181a2674e03SMichael Tuexen 	fputs("[", fp);
1182a2674e03SMichael Tuexen 	for (i = 0; i < iovcnt; i++) {
1183a2674e03SMichael Tuexen 		len = iov[i].iov_len;
1184a2674e03SMichael Tuexen 		if (len > max_string) {
1185a2674e03SMichael Tuexen 			len = max_string;
1186a2674e03SMichael Tuexen 			buf_truncated = true;
1187a2674e03SMichael Tuexen 		} else {
1188a2674e03SMichael Tuexen 			buf_truncated = false;
1189a2674e03SMichael Tuexen 		}
1190a2674e03SMichael Tuexen 		fprintf(fp, "%s{", (i > 0) ? "," : "");
1191cc86d14aSBrooks Davis 		if (len && get_struct(pid, (uintptr_t)iov[i].iov_base, &tmp2, len) != -1) {
1192a2674e03SMichael Tuexen 			tmp3 = malloc(len * 4 + 1);
1193a2674e03SMichael Tuexen 			while (len) {
1194a2674e03SMichael Tuexen 				if (strvisx(tmp3, tmp2, len,
1195a2674e03SMichael Tuexen 				    VIS_CSTYLE|VIS_TAB|VIS_NL) <=
1196a2674e03SMichael Tuexen 				    (int)max_string)
1197a2674e03SMichael Tuexen 					break;
1198a2674e03SMichael Tuexen 				len--;
1199a2674e03SMichael Tuexen 				buf_truncated = true;
1200a2674e03SMichael Tuexen 			}
1201a2674e03SMichael Tuexen 			fprintf(fp, "\"%s\"%s", tmp3,
1202a2674e03SMichael Tuexen 			    buf_truncated ? "..." : "");
1203a2674e03SMichael Tuexen 			free(tmp3);
1204a2674e03SMichael Tuexen 		} else {
1205cc86d14aSBrooks Davis 			print_pointer(fp, (uintptr_t)iov[i].iov_base);
1206a2674e03SMichael Tuexen 		}
1207a2674e03SMichael Tuexen 		fprintf(fp, ",%zu}", iov[i].iov_len);
1208a2674e03SMichael Tuexen 	}
1209a2674e03SMichael Tuexen 	fprintf(fp, "%s%s", iov_truncated ? ",..." : "", "]");
1210a2674e03SMichael Tuexen }
1211a2674e03SMichael Tuexen 
1212a2674e03SMichael Tuexen static void
1213bb24ee2bSThomas Munro print_sigval(FILE *fp, union sigval *sv)
1214bb24ee2bSThomas Munro {
1215bb24ee2bSThomas Munro 	fprintf(fp, "{ %d, %p }", sv->sival_int, sv->sival_ptr);
1216bb24ee2bSThomas Munro }
1217bb24ee2bSThomas Munro 
1218bb24ee2bSThomas Munro static void
1219bb24ee2bSThomas Munro print_sigevent(FILE *fp, struct sigevent *se)
1220bb24ee2bSThomas Munro {
1221bb24ee2bSThomas Munro 	fputs("{ sigev_notify=", fp);
1222bb24ee2bSThomas Munro 	switch (se->sigev_notify) {
1223bb24ee2bSThomas Munro 	case SIGEV_NONE:
1224bb24ee2bSThomas Munro 		fputs("SIGEV_NONE", fp);
1225bb24ee2bSThomas Munro 		break;
1226bb24ee2bSThomas Munro 	case SIGEV_SIGNAL:
1227bb24ee2bSThomas Munro 		fprintf(fp, "SIGEV_SIGNAL, sigev_signo=%s, sigev_value=",
1228bb24ee2bSThomas Munro 				strsig2(se->sigev_signo));
1229bb24ee2bSThomas Munro 		print_sigval(fp, &se->sigev_value);
1230bb24ee2bSThomas Munro 		break;
1231bb24ee2bSThomas Munro 	case SIGEV_THREAD:
1232bb24ee2bSThomas Munro 		fputs("SIGEV_THREAD, sigev_value=", fp);
1233bb24ee2bSThomas Munro 		print_sigval(fp, &se->sigev_value);
1234bb24ee2bSThomas Munro 		break;
1235bb24ee2bSThomas Munro 	case SIGEV_KEVENT:
1236bb24ee2bSThomas Munro 		fprintf(fp, "SIGEV_KEVENT, sigev_notify_kqueue=%d, sigev_notify_kevent_flags=",
1237bb24ee2bSThomas Munro 				se->sigev_notify_kqueue);
1238bb24ee2bSThomas Munro 		print_mask_arg(sysdecode_kevent_flags, fp, se->sigev_notify_kevent_flags);
1239bb24ee2bSThomas Munro 		break;
1240bb24ee2bSThomas Munro 	case SIGEV_THREAD_ID:
1241bb24ee2bSThomas Munro 		fprintf(fp, "SIGEV_THREAD_ID, sigev_notify_thread_id=%d, sigev_signo=%s, sigev_value=",
1242bb24ee2bSThomas Munro 				se->sigev_notify_thread_id, strsig2(se->sigev_signo));
1243bb24ee2bSThomas Munro 		print_sigval(fp, &se->sigev_value);
1244bb24ee2bSThomas Munro 		break;
1245bb24ee2bSThomas Munro 	default:
1246bb24ee2bSThomas Munro 		fprintf(fp, "%d", se->sigev_notify);
1247bb24ee2bSThomas Munro 		break;
1248bb24ee2bSThomas Munro 	}
1249bb24ee2bSThomas Munro 	fputs(" }", fp);
1250bb24ee2bSThomas Munro }
1251bb24ee2bSThomas Munro 
1252bb24ee2bSThomas Munro static void
1253bb24ee2bSThomas Munro print_aiocb(FILE *fp, struct aiocb *cb)
1254bb24ee2bSThomas Munro {
1255bb24ee2bSThomas Munro 	fprintf(fp, "{ %d,%jd,%p,%zu,%s,",
1256bb24ee2bSThomas Munro 			cb->aio_fildes,
1257bb24ee2bSThomas Munro 			cb->aio_offset,
1258bb24ee2bSThomas Munro 			cb->aio_buf,
1259bb24ee2bSThomas Munro 			cb->aio_nbytes,
1260bb24ee2bSThomas Munro 			xlookup(lio_opcodes, cb->aio_lio_opcode));
1261bb24ee2bSThomas Munro 	print_sigevent(fp, &cb->aio_sigevent);
1262bb24ee2bSThomas Munro 	fputs(" }", fp);
1263bb24ee2bSThomas Munro }
1264bb24ee2bSThomas Munro 
1265bb24ee2bSThomas Munro static void
1266a2674e03SMichael Tuexen print_gen_cmsg(FILE *fp, struct cmsghdr *cmsghdr)
1267a2674e03SMichael Tuexen {
1268a2674e03SMichael Tuexen 	u_char *q;
1269a2674e03SMichael Tuexen 
1270a2674e03SMichael Tuexen 	fputs("{", fp);
1271a2674e03SMichael Tuexen 	for (q = CMSG_DATA(cmsghdr);
1272a2674e03SMichael Tuexen 	     q < (u_char *)cmsghdr + cmsghdr->cmsg_len; q++) {
1273a2674e03SMichael Tuexen 		fprintf(fp, "%s0x%02x", q == CMSG_DATA(cmsghdr) ? "" : ",", *q);
1274a2674e03SMichael Tuexen 	}
1275a2674e03SMichael Tuexen 	fputs("}", fp);
1276a2674e03SMichael Tuexen }
1277a2674e03SMichael Tuexen 
1278a2674e03SMichael Tuexen static void
1279a2674e03SMichael Tuexen print_sctp_initmsg(FILE *fp, struct sctp_initmsg *init)
1280a2674e03SMichael Tuexen {
1281a2674e03SMichael Tuexen 	fprintf(fp, "{out=%u,", init->sinit_num_ostreams);
1282a2674e03SMichael Tuexen 	fprintf(fp, "in=%u,", init->sinit_max_instreams);
1283a2674e03SMichael Tuexen 	fprintf(fp, "max_rtx=%u,", init->sinit_max_attempts);
1284a2674e03SMichael Tuexen 	fprintf(fp, "max_rto=%u}", init->sinit_max_init_timeo);
1285a2674e03SMichael Tuexen }
1286a2674e03SMichael Tuexen 
1287a2674e03SMichael Tuexen static void
128876785d6eSJohn Baldwin print_sctp_sndrcvinfo(FILE *fp, bool receive, struct sctp_sndrcvinfo *info)
1289a2674e03SMichael Tuexen {
1290a2674e03SMichael Tuexen 	fprintf(fp, "{sid=%u,", info->sinfo_stream);
129176785d6eSJohn Baldwin 	if (receive) {
1292a2674e03SMichael Tuexen 		fprintf(fp, "ssn=%u,", info->sinfo_ssn);
1293a2674e03SMichael Tuexen 	}
1294a2674e03SMichael Tuexen 	fputs("flgs=", fp);
1295a2674e03SMichael Tuexen 	sysdecode_sctp_sinfo_flags(fp, info->sinfo_flags);
1296a2674e03SMichael Tuexen 	fprintf(fp, ",ppid=%u,", ntohl(info->sinfo_ppid));
129776785d6eSJohn Baldwin 	if (!receive) {
1298a2674e03SMichael Tuexen 		fprintf(fp, "ctx=%u,", info->sinfo_context);
1299a2674e03SMichael Tuexen 		fprintf(fp, "ttl=%u,", info->sinfo_timetolive);
1300a2674e03SMichael Tuexen 	}
130176785d6eSJohn Baldwin 	if (receive) {
1302a2674e03SMichael Tuexen 		fprintf(fp, "tsn=%u,", info->sinfo_tsn);
1303a2674e03SMichael Tuexen 		fprintf(fp, "cumtsn=%u,", info->sinfo_cumtsn);
1304a2674e03SMichael Tuexen 	}
1305a2674e03SMichael Tuexen 	fprintf(fp, "id=%u}", info->sinfo_assoc_id);
1306a2674e03SMichael Tuexen }
1307a2674e03SMichael Tuexen 
1308a2674e03SMichael Tuexen static void
1309a2674e03SMichael Tuexen print_sctp_sndinfo(FILE *fp, struct sctp_sndinfo *info)
1310a2674e03SMichael Tuexen {
1311a2674e03SMichael Tuexen 	fprintf(fp, "{sid=%u,", info->snd_sid);
1312a2674e03SMichael Tuexen 	fputs("flgs=", fp);
1313a2674e03SMichael Tuexen 	print_mask_arg(sysdecode_sctp_snd_flags, fp, info->snd_flags);
1314a2674e03SMichael Tuexen 	fprintf(fp, ",ppid=%u,", ntohl(info->snd_ppid));
1315a2674e03SMichael Tuexen 	fprintf(fp, "ctx=%u,", info->snd_context);
1316a2674e03SMichael Tuexen 	fprintf(fp, "id=%u}", info->snd_assoc_id);
1317a2674e03SMichael Tuexen }
1318a2674e03SMichael Tuexen 
1319a2674e03SMichael Tuexen static void
1320a2674e03SMichael Tuexen print_sctp_rcvinfo(FILE *fp, struct sctp_rcvinfo *info)
1321a2674e03SMichael Tuexen {
1322a2674e03SMichael Tuexen 	fprintf(fp, "{sid=%u,", info->rcv_sid);
1323a2674e03SMichael Tuexen 	fprintf(fp, "ssn=%u,", info->rcv_ssn);
1324a2674e03SMichael Tuexen 	fputs("flgs=", fp);
1325a2674e03SMichael Tuexen 	print_mask_arg(sysdecode_sctp_rcv_flags, fp, info->rcv_flags);
1326a2674e03SMichael Tuexen 	fprintf(fp, ",ppid=%u,", ntohl(info->rcv_ppid));
1327a2674e03SMichael Tuexen 	fprintf(fp, "tsn=%u,", info->rcv_tsn);
1328a2674e03SMichael Tuexen 	fprintf(fp, "cumtsn=%u,", info->rcv_cumtsn);
1329a2674e03SMichael Tuexen 	fprintf(fp, "ctx=%u,", info->rcv_context);
1330a2674e03SMichael Tuexen 	fprintf(fp, "id=%u}", info->rcv_assoc_id);
1331a2674e03SMichael Tuexen }
1332a2674e03SMichael Tuexen 
1333a2674e03SMichael Tuexen static void
1334a2674e03SMichael Tuexen print_sctp_nxtinfo(FILE *fp, struct sctp_nxtinfo *info)
1335a2674e03SMichael Tuexen {
1336a2674e03SMichael Tuexen 	fprintf(fp, "{sid=%u,", info->nxt_sid);
1337a2674e03SMichael Tuexen 	fputs("flgs=", fp);
1338a2674e03SMichael Tuexen 	print_mask_arg(sysdecode_sctp_nxt_flags, fp, info->nxt_flags);
1339a2674e03SMichael Tuexen 	fprintf(fp, ",ppid=%u,", ntohl(info->nxt_ppid));
1340a2674e03SMichael Tuexen 	fprintf(fp, "len=%u,", info->nxt_length);
1341a2674e03SMichael Tuexen 	fprintf(fp, "id=%u}", info->nxt_assoc_id);
1342a2674e03SMichael Tuexen }
1343a2674e03SMichael Tuexen 
1344a2674e03SMichael Tuexen static void
1345a2674e03SMichael Tuexen print_sctp_prinfo(FILE *fp, struct sctp_prinfo *info)
1346a2674e03SMichael Tuexen {
1347a2674e03SMichael Tuexen 	fputs("{pol=", fp);
1348a2674e03SMichael Tuexen 	print_integer_arg(sysdecode_sctp_pr_policy, fp, info->pr_policy);
1349a2674e03SMichael Tuexen 	fprintf(fp, ",val=%u}", info->pr_value);
1350a2674e03SMichael Tuexen }
1351a2674e03SMichael Tuexen 
1352a2674e03SMichael Tuexen static void
1353a2674e03SMichael Tuexen print_sctp_authinfo(FILE *fp, struct sctp_authinfo *info)
1354a2674e03SMichael Tuexen {
1355a2674e03SMichael Tuexen 	fprintf(fp, "{num=%u}", info->auth_keynumber);
1356a2674e03SMichael Tuexen }
1357a2674e03SMichael Tuexen 
1358a2674e03SMichael Tuexen static void
1359a2674e03SMichael Tuexen print_sctp_ipv4_addr(FILE *fp, struct in_addr *addr)
1360a2674e03SMichael Tuexen {
1361a2674e03SMichael Tuexen 	char buf[INET_ADDRSTRLEN];
1362a2674e03SMichael Tuexen 	const char *s;
1363a2674e03SMichael Tuexen 
1364a2674e03SMichael Tuexen 	s = inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
1365a2674e03SMichael Tuexen 	if (s != NULL)
1366a2674e03SMichael Tuexen 		fprintf(fp, "{addr=%s}", s);
1367a2674e03SMichael Tuexen 	else
1368a2674e03SMichael Tuexen 		fputs("{addr=???}", fp);
1369a2674e03SMichael Tuexen }
1370a2674e03SMichael Tuexen 
1371a2674e03SMichael Tuexen static void
1372a2674e03SMichael Tuexen print_sctp_ipv6_addr(FILE *fp, struct in6_addr *addr)
1373a2674e03SMichael Tuexen {
1374a2674e03SMichael Tuexen 	char buf[INET6_ADDRSTRLEN];
1375a2674e03SMichael Tuexen 	const char *s;
1376a2674e03SMichael Tuexen 
1377a2674e03SMichael Tuexen 	s = inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN);
1378a2674e03SMichael Tuexen 	if (s != NULL)
1379a2674e03SMichael Tuexen 		fprintf(fp, "{addr=%s}", s);
1380a2674e03SMichael Tuexen 	else
1381a2674e03SMichael Tuexen 		fputs("{addr=???}", fp);
1382a2674e03SMichael Tuexen }
1383a2674e03SMichael Tuexen 
1384a2674e03SMichael Tuexen static void
138576785d6eSJohn Baldwin print_sctp_cmsg(FILE *fp, bool receive, struct cmsghdr *cmsghdr)
1386a2674e03SMichael Tuexen {
1387a2674e03SMichael Tuexen 	void *data;
1388a2674e03SMichael Tuexen 	socklen_t len;
1389a2674e03SMichael Tuexen 
1390a2674e03SMichael Tuexen 	len = cmsghdr->cmsg_len;
1391a2674e03SMichael Tuexen 	data = CMSG_DATA(cmsghdr);
1392a2674e03SMichael Tuexen 	switch (cmsghdr->cmsg_type) {
1393a2674e03SMichael Tuexen 	case SCTP_INIT:
1394a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_initmsg)))
1395a2674e03SMichael Tuexen 			print_sctp_initmsg(fp, (struct sctp_initmsg *)data);
1396a2674e03SMichael Tuexen 		else
1397a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1398a2674e03SMichael Tuexen 		break;
1399a2674e03SMichael Tuexen 	case SCTP_SNDRCV:
1400a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_sndrcvinfo)))
140176785d6eSJohn Baldwin 			print_sctp_sndrcvinfo(fp, receive,
1402a2674e03SMichael Tuexen 			    (struct sctp_sndrcvinfo *)data);
1403a2674e03SMichael Tuexen 		else
1404a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1405a2674e03SMichael Tuexen 		break;
1406a2674e03SMichael Tuexen #if 0
1407a2674e03SMichael Tuexen 	case SCTP_EXTRCV:
1408a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_extrcvinfo)))
1409a2674e03SMichael Tuexen 			print_sctp_extrcvinfo(fp,
1410a2674e03SMichael Tuexen 			    (struct sctp_extrcvinfo *)data);
1411a2674e03SMichael Tuexen 		else
1412a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1413a2674e03SMichael Tuexen 		break;
1414a2674e03SMichael Tuexen #endif
1415a2674e03SMichael Tuexen 	case SCTP_SNDINFO:
1416a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_sndinfo)))
1417a2674e03SMichael Tuexen 			print_sctp_sndinfo(fp, (struct sctp_sndinfo *)data);
1418a2674e03SMichael Tuexen 		else
1419a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1420a2674e03SMichael Tuexen 		break;
1421a2674e03SMichael Tuexen 	case SCTP_RCVINFO:
1422a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_rcvinfo)))
1423a2674e03SMichael Tuexen 			print_sctp_rcvinfo(fp, (struct sctp_rcvinfo *)data);
1424a2674e03SMichael Tuexen 		else
1425a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1426a2674e03SMichael Tuexen 		break;
1427a2674e03SMichael Tuexen 	case SCTP_NXTINFO:
1428a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_nxtinfo)))
1429a2674e03SMichael Tuexen 			print_sctp_nxtinfo(fp, (struct sctp_nxtinfo *)data);
1430a2674e03SMichael Tuexen 		else
1431a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1432a2674e03SMichael Tuexen 		break;
1433a2674e03SMichael Tuexen 	case SCTP_PRINFO:
1434a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_prinfo)))
1435a2674e03SMichael Tuexen 			print_sctp_prinfo(fp, (struct sctp_prinfo *)data);
1436a2674e03SMichael Tuexen 		else
1437a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1438a2674e03SMichael Tuexen 		break;
1439a2674e03SMichael Tuexen 	case SCTP_AUTHINFO:
1440a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct sctp_authinfo)))
1441a2674e03SMichael Tuexen 			print_sctp_authinfo(fp, (struct sctp_authinfo *)data);
1442a2674e03SMichael Tuexen 		else
1443a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1444a2674e03SMichael Tuexen 		break;
1445a2674e03SMichael Tuexen 	case SCTP_DSTADDRV4:
1446a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct in_addr)))
1447a2674e03SMichael Tuexen 			print_sctp_ipv4_addr(fp, (struct in_addr *)data);
1448a2674e03SMichael Tuexen 		else
1449a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1450a2674e03SMichael Tuexen 		break;
1451a2674e03SMichael Tuexen 	case SCTP_DSTADDRV6:
1452a2674e03SMichael Tuexen 		if (len == CMSG_LEN(sizeof(struct in6_addr)))
1453a2674e03SMichael Tuexen 			print_sctp_ipv6_addr(fp, (struct in6_addr *)data);
1454a2674e03SMichael Tuexen 		else
1455a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1456a2674e03SMichael Tuexen 		break;
1457a2674e03SMichael Tuexen 	default:
1458a2674e03SMichael Tuexen 		print_gen_cmsg(fp, cmsghdr);
1459a2674e03SMichael Tuexen 	}
1460a2674e03SMichael Tuexen }
1461a2674e03SMichael Tuexen 
1462a2674e03SMichael Tuexen static void
146376785d6eSJohn Baldwin print_cmsgs(FILE *fp, pid_t pid, bool receive, struct msghdr *msghdr)
1464a2674e03SMichael Tuexen {
1465a2674e03SMichael Tuexen 	struct cmsghdr *cmsghdr;
1466a2674e03SMichael Tuexen 	char *cmsgbuf;
1467a2674e03SMichael Tuexen 	const char *temp;
1468a2674e03SMichael Tuexen 	socklen_t len;
1469a2674e03SMichael Tuexen 	int level, type;
1470a2674e03SMichael Tuexen 	bool first;
1471a2674e03SMichael Tuexen 
1472a2674e03SMichael Tuexen 	len = msghdr->msg_controllen;
14736accaf4aSMichael Tuexen 	if (len == 0) {
14746accaf4aSMichael Tuexen 		fputs("{}", fp);
14756accaf4aSMichael Tuexen 		return;
14766accaf4aSMichael Tuexen 	}
1477a2674e03SMichael Tuexen 	cmsgbuf = calloc(1, len);
1478cc86d14aSBrooks Davis 	if (get_struct(pid, (uintptr_t)msghdr->msg_control, cmsgbuf, len) == -1) {
1479cc86d14aSBrooks Davis 		print_pointer(fp, (uintptr_t)msghdr->msg_control);
1480a2674e03SMichael Tuexen 		free(cmsgbuf);
14816accaf4aSMichael Tuexen 		return;
1482a2674e03SMichael Tuexen 	}
1483a2674e03SMichael Tuexen 	msghdr->msg_control = cmsgbuf;
1484a2674e03SMichael Tuexen 	first = true;
1485a2674e03SMichael Tuexen 	fputs("{", fp);
1486a2674e03SMichael Tuexen 	for (cmsghdr = CMSG_FIRSTHDR(msghdr);
1487a2674e03SMichael Tuexen 	   cmsghdr != NULL;
1488a2674e03SMichael Tuexen 	   cmsghdr = CMSG_NXTHDR(msghdr, cmsghdr)) {
14894b0c6fa0SMark Johnston 		if (cmsghdr->cmsg_len < sizeof(*cmsghdr)) {
14904b0c6fa0SMark Johnston 			fprintf(fp, "{<invalid cmsg, len=%u>}",
14914b0c6fa0SMark Johnston 			    cmsghdr->cmsg_len);
14924b0c6fa0SMark Johnston 			if (cmsghdr->cmsg_len == 0) {
14934b0c6fa0SMark Johnston 				/* Avoid looping forever. */
14944b0c6fa0SMark Johnston 				break;
14954b0c6fa0SMark Johnston 			}
14964b0c6fa0SMark Johnston 			continue;
14974b0c6fa0SMark Johnston 		}
14984b0c6fa0SMark Johnston 
1499a2674e03SMichael Tuexen 		level = cmsghdr->cmsg_level;
1500a2674e03SMichael Tuexen 		type = cmsghdr->cmsg_type;
1501a2674e03SMichael Tuexen 		len = cmsghdr->cmsg_len;
1502a2674e03SMichael Tuexen 		fprintf(fp, "%s{level=", first ? "" : ",");
1503a2674e03SMichael Tuexen 		print_integer_arg(sysdecode_sockopt_level, fp, level);
1504a2674e03SMichael Tuexen 		fputs(",type=", fp);
1505a2674e03SMichael Tuexen 		temp = sysdecode_cmsg_type(level, type);
1506a2674e03SMichael Tuexen 		if (temp) {
1507a2674e03SMichael Tuexen 			fputs(temp, fp);
1508a2674e03SMichael Tuexen 		} else {
1509a2674e03SMichael Tuexen 			fprintf(fp, "%d", type);
1510a2674e03SMichael Tuexen 		}
1511a2674e03SMichael Tuexen 		fputs(",data=", fp);
1512a2674e03SMichael Tuexen 		switch (level) {
1513a2674e03SMichael Tuexen 		case IPPROTO_SCTP:
151476785d6eSJohn Baldwin 			print_sctp_cmsg(fp, receive, cmsghdr);
1515a2674e03SMichael Tuexen 			break;
1516a2674e03SMichael Tuexen 		default:
1517a2674e03SMichael Tuexen 			print_gen_cmsg(fp, cmsghdr);
1518a2674e03SMichael Tuexen 			break;
1519a2674e03SMichael Tuexen 		}
1520a2674e03SMichael Tuexen 		fputs("}", fp);
1521b8ff144eSMichael Tuexen 		first = false;
1522a2674e03SMichael Tuexen 	}
1523a2674e03SMichael Tuexen 	fputs("}", fp);
1524a2674e03SMichael Tuexen 	free(cmsgbuf);
1525a2674e03SMichael Tuexen }
1526a2674e03SMichael Tuexen 
152743ce0d90SKonstantin Belousov static void
152843ec732aSPawel Biernacki print_sysctl_oid(FILE *fp, int *oid, size_t len)
152943ce0d90SKonstantin Belousov {
153043ec732aSPawel Biernacki 	size_t i;
153143ec732aSPawel Biernacki 	bool first;
153243ce0d90SKonstantin Belousov 
153343ec732aSPawel Biernacki 	first = true;
153443ec732aSPawel Biernacki 	fprintf(fp, "{ ");
153543ec732aSPawel Biernacki 	for (i = 0; i < len; i++) {
153643ec732aSPawel Biernacki 		fprintf(fp, "%s%d", first ? "" : ".", oid[i]);
153743ec732aSPawel Biernacki 		first = false;
153843ec732aSPawel Biernacki 	}
153943ec732aSPawel Biernacki 	fprintf(fp, " }");
154043ec732aSPawel Biernacki }
154143ec732aSPawel Biernacki 
154243ec732aSPawel Biernacki static void
154343ec732aSPawel Biernacki print_sysctl(FILE *fp, int *oid, size_t len)
154443ec732aSPawel Biernacki {
154543ec732aSPawel Biernacki 	char name[BUFSIZ];
154643ec732aSPawel Biernacki 	int qoid[CTL_MAXNAME + 2];
154743ec732aSPawel Biernacki 	size_t i;
154843ec732aSPawel Biernacki 
154943ec732aSPawel Biernacki 	qoid[0] = CTL_SYSCTL;
155043ec732aSPawel Biernacki 	qoid[1] = CTL_SYSCTL_NAME;
155143ec732aSPawel Biernacki 	memcpy(qoid + 2, oid, len * sizeof(int));
155243ec732aSPawel Biernacki 	i = sizeof(name);
155343ec732aSPawel Biernacki 	if (sysctl(qoid, len + 2, name, &i, 0, 0) == -1)
155443ec732aSPawel Biernacki 		print_sysctl_oid(fp, oid, len);
155543ec732aSPawel Biernacki 	else
155643ec732aSPawel Biernacki 		fprintf(fp, "%s", name);
155743ce0d90SKonstantin Belousov }
155843ce0d90SKonstantin Belousov 
1559bbeaf6c0SSean Eric Fagan /*
156031dddc6aSAlex Richardson  * Convert a 32-bit user-space pointer to psaddr_t. Currently, this
156131dddc6aSAlex Richardson  * sign-extends on MIPS and zero-extends on all other architectures.
156231dddc6aSAlex Richardson  */
156331dddc6aSAlex Richardson static psaddr_t
156431dddc6aSAlex Richardson user_ptr32_to_psaddr(int32_t user_pointer)
156531dddc6aSAlex Richardson {
156631dddc6aSAlex Richardson #if defined(__mips__)
156731dddc6aSAlex Richardson 	return ((psaddr_t)(intptr_t)user_pointer);
156831dddc6aSAlex Richardson #else
156931dddc6aSAlex Richardson 	return ((psaddr_t)(uintptr_t)user_pointer);
157031dddc6aSAlex Richardson #endif
157131dddc6aSAlex Richardson }
157231dddc6aSAlex Richardson 
157331dddc6aSAlex Richardson /*
1574bbeaf6c0SSean Eric Fagan  * Converts a syscall argument into a string.  Said string is
15754e3da534SJohn Baldwin  * allocated via malloc(), so needs to be free()'d.  sc is
1576bbeaf6c0SSean Eric Fagan  * a pointer to the syscall description (see above); args is
1577bbeaf6c0SSean Eric Fagan  * an array of all of the system call arguments.
1578bbeaf6c0SSean Eric Fagan  */
1579bbeaf6c0SSean Eric Fagan char *
1580b1ad6a90SBrooks Davis print_arg(struct syscall_arg *sc, syscallarg_t *args, syscallarg_t *retval,
158194355cfdSAndrey Zonov     struct trussinfo *trussinfo)
1582d8984f48SDag-Erling Smørgrav {
1583f083f689SJohn Baldwin 	FILE *fp;
158494355cfdSAndrey Zonov 	char *tmp;
1585f083f689SJohn Baldwin 	size_t tmplen;
158694355cfdSAndrey Zonov 	pid_t pid;
1587d8984f48SDag-Erling Smørgrav 
1588f083f689SJohn Baldwin 	fp = open_memstream(&tmp, &tmplen);
15892b75c8adSJohn Baldwin 	pid = trussinfo->curthread->proc->pid;
1590bbeaf6c0SSean Eric Fagan 	switch (sc->type & ARG_MASK) {
1591bbeaf6c0SSean Eric Fagan 	case Hex:
1592f083f689SJohn Baldwin 		fprintf(fp, "0x%x", (int)args[sc->offset]);
1593bbeaf6c0SSean Eric Fagan 		break;
1594bbeaf6c0SSean Eric Fagan 	case Octal:
1595f083f689SJohn Baldwin 		fprintf(fp, "0%o", (int)args[sc->offset]);
1596bbeaf6c0SSean Eric Fagan 		break;
1597bbeaf6c0SSean Eric Fagan 	case Int:
1598f083f689SJohn Baldwin 		fprintf(fp, "%d", (int)args[sc->offset]);
1599bbeaf6c0SSean Eric Fagan 		break;
1600808d9805SEd Schouten 	case UInt:
1601808d9805SEd Schouten 		fprintf(fp, "%u", (unsigned int)args[sc->offset]);
1602808d9805SEd Schouten 		break;
1603ebb2cc40SJohn Baldwin 	case PUInt: {
1604ebb2cc40SJohn Baldwin 		unsigned int val;
1605ebb2cc40SJohn Baldwin 
1606cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &val,
1607ebb2cc40SJohn Baldwin 		    sizeof(val)) == 0)
1608ebb2cc40SJohn Baldwin 			fprintf(fp, "{ %u }", val);
1609ebb2cc40SJohn Baldwin 		else
1610cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1611ebb2cc40SJohn Baldwin 		break;
1612ebb2cc40SJohn Baldwin 	}
1613fdb5bf37SJohn Baldwin 	case LongHex:
1614b1ad6a90SBrooks Davis 		fprintf(fp, "0x%lx", (long)args[sc->offset]);
1615fdb5bf37SJohn Baldwin 		break;
1616b289a8d7SJohn Baldwin 	case Long:
1617b1ad6a90SBrooks Davis 		fprintf(fp, "%ld", (long)args[sc->offset]);
1618b289a8d7SJohn Baldwin 		break;
1619e261fb2aSJohn Baldwin 	case Sizet:
1620e261fb2aSJohn Baldwin 		fprintf(fp, "%zu", (size_t)args[sc->offset]);
1621e261fb2aSJohn Baldwin 		break;
16225b05dc5aSThomas Munro 	case ShmName:
16235b05dc5aSThomas Munro 		/* Handle special SHM_ANON value. */
162431dddc6aSAlex Richardson 		if ((char *)(uintptr_t)args[sc->offset] == SHM_ANON) {
16255b05dc5aSThomas Munro 			fprintf(fp, "SHM_ANON");
16265b05dc5aSThomas Munro 			break;
16275b05dc5aSThomas Munro 		}
16285b05dc5aSThomas Munro 		/* FALLTHROUGH */
1629d8984f48SDag-Erling Smørgrav 	case Name: {
1630081e5c48SPav Lucistnik 		/* NULL-terminated string. */
1631bbeaf6c0SSean Eric Fagan 		char *tmp2;
16324e3da534SJohn Baldwin 
1633cc86d14aSBrooks Davis 		tmp2 = get_string(pid, args[sc->offset], 0);
1634f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
1635bbeaf6c0SSean Eric Fagan 		free(tmp2);
1636bbeaf6c0SSean Eric Fagan 		break;
1637d8984f48SDag-Erling Smørgrav 	}
1638d8984f48SDag-Erling Smørgrav 	case BinString: {
16394e3da534SJohn Baldwin 		/*
16404e3da534SJohn Baldwin 		 * Binary block of data that might have printable characters.
16414e3da534SJohn Baldwin 		 * XXX If type|OUT, assume that the length is the syscall's
16424e3da534SJohn Baldwin 		 * return value.  Otherwise, assume that the length of the block
16434e3da534SJohn Baldwin 		 * is in the next syscall argument.
16444e3da534SJohn Baldwin 		 */
1645081e5c48SPav Lucistnik 		int max_string = trussinfo->strsize;
1646081e5c48SPav Lucistnik 		char tmp2[max_string + 1], *tmp3;
1647081e5c48SPav Lucistnik 		int len;
1648081e5c48SPav Lucistnik 		int truncated = 0;
1649081e5c48SPav Lucistnik 
1650081e5c48SPav Lucistnik 		if (sc->type & OUT)
16512b75c8adSJohn Baldwin 			len = retval[0];
1652081e5c48SPav Lucistnik 		else
1653081e5c48SPav Lucistnik 			len = args[sc->offset + 1];
1654081e5c48SPav Lucistnik 
16554e3da534SJohn Baldwin 		/*
16564e3da534SJohn Baldwin 		 * Don't print more than max_string characters, to avoid word
16574e3da534SJohn Baldwin 		 * wrap.  If we have to truncate put some ... after the string.
1658081e5c48SPav Lucistnik 		 */
1659081e5c48SPav Lucistnik 		if (len > max_string) {
1660081e5c48SPav Lucistnik 			len = max_string;
1661081e5c48SPav Lucistnik 			truncated = 1;
1662081e5c48SPav Lucistnik 		}
1663cc86d14aSBrooks Davis 		if (len && get_struct(pid, args[sc->offset], &tmp2, len)
166494355cfdSAndrey Zonov 		    != -1) {
1665081e5c48SPav Lucistnik 			tmp3 = malloc(len * 4 + 1);
1666081e5c48SPav Lucistnik 			while (len) {
166794355cfdSAndrey Zonov 				if (strvisx(tmp3, tmp2, len,
166894355cfdSAndrey Zonov 				    VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
1669081e5c48SPav Lucistnik 					break;
1670081e5c48SPav Lucistnik 				len--;
1671081e5c48SPav Lucistnik 				truncated = 1;
167280c7cc1cSPedro F. Giffuni 			}
1673f083f689SJohn Baldwin 			fprintf(fp, "\"%s\"%s", tmp3, truncated ?
167494355cfdSAndrey Zonov 			    "..." : "");
1675081e5c48SPav Lucistnik 			free(tmp3);
1676d8984f48SDag-Erling Smørgrav 		} else {
1677cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1678081e5c48SPav Lucistnik 		}
1679081e5c48SPav Lucistnik 		break;
1680d8984f48SDag-Erling Smørgrav 	}
168168055893SJohn Baldwin 	case ExecArgs:
168268055893SJohn Baldwin 	case ExecEnv:
1683d8984f48SDag-Erling Smørgrav 	case StringArray: {
168431dddc6aSAlex Richardson 		psaddr_t addr;
1685890843c1SJohn Baldwin 		union {
16867daca4e2SAlex Richardson 			int32_t strarray32[PAGE_SIZE / sizeof(int32_t)];
16877daca4e2SAlex Richardson 			int64_t strarray64[PAGE_SIZE / sizeof(int64_t)];
1688890843c1SJohn Baldwin 			char buf[PAGE_SIZE];
1689890843c1SJohn Baldwin 		} u;
16909897b203SMatthew N. Dodd 		char *string;
1691890843c1SJohn Baldwin 		size_t len;
16922b75c8adSJohn Baldwin 		u_int first, i;
16937daca4e2SAlex Richardson 		size_t pointer_size =
16947daca4e2SAlex Richardson 		    trussinfo->curthread->proc->abi->pointer_size;
16959897b203SMatthew N. Dodd 
1696890843c1SJohn Baldwin 		/*
169768055893SJohn Baldwin 		 * Only parse argv[] and environment arrays from exec calls
169868055893SJohn Baldwin 		 * if requested.
169968055893SJohn Baldwin 		 */
170068055893SJohn Baldwin 		if (((sc->type & ARG_MASK) == ExecArgs &&
170168055893SJohn Baldwin 		    (trussinfo->flags & EXECVEARGS) == 0) ||
170268055893SJohn Baldwin 		    ((sc->type & ARG_MASK) == ExecEnv &&
170368055893SJohn Baldwin 		    (trussinfo->flags & EXECVEENVS) == 0)) {
1704cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
170568055893SJohn Baldwin 			break;
170668055893SJohn Baldwin 		}
170768055893SJohn Baldwin 
170868055893SJohn Baldwin 		/*
1709890843c1SJohn Baldwin 		 * Read a page of pointers at a time.  Punt if the top-level
1710890843c1SJohn Baldwin 		 * pointer is not aligned.  Note that the first read is of
1711890843c1SJohn Baldwin 		 * a partial page.
1712890843c1SJohn Baldwin 		 */
1713890843c1SJohn Baldwin 		addr = args[sc->offset];
171431dddc6aSAlex Richardson 		if (!__is_aligned(addr, pointer_size)) {
1715cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1716890843c1SJohn Baldwin 			break;
17179897b203SMatthew N. Dodd 		}
17189897b203SMatthew N. Dodd 
1719890843c1SJohn Baldwin 		len = PAGE_SIZE - (addr & PAGE_MASK);
1720cc86d14aSBrooks Davis 		if (get_struct(pid, addr, u.buf, len) == -1) {
1721cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1722890843c1SJohn Baldwin 			break;
17239897b203SMatthew N. Dodd 		}
17247daca4e2SAlex Richardson 		assert(len > 0);
1725890843c1SJohn Baldwin 
1726890843c1SJohn Baldwin 		fputc('[', fp);
1727890843c1SJohn Baldwin 		first = 1;
1728890843c1SJohn Baldwin 		i = 0;
17297daca4e2SAlex Richardson 		for (;;) {
173031dddc6aSAlex Richardson 			psaddr_t straddr;
17317daca4e2SAlex Richardson 			if (pointer_size == 4) {
173231dddc6aSAlex Richardson 				straddr = user_ptr32_to_psaddr(u.strarray32[i]);
17337daca4e2SAlex Richardson 			} else if (pointer_size == 8) {
173431dddc6aSAlex Richardson 				straddr = (psaddr_t)u.strarray64[i];
17357daca4e2SAlex Richardson 			} else {
17367daca4e2SAlex Richardson 				errx(1, "Unsupported pointer size: %zu",
17377daca4e2SAlex Richardson 				    pointer_size);
17387daca4e2SAlex Richardson 			}
173931dddc6aSAlex Richardson 
174031dddc6aSAlex Richardson 			/* Stop once we read the first NULL pointer. */
174131dddc6aSAlex Richardson 			if (straddr == 0)
174231dddc6aSAlex Richardson 				break;
17437daca4e2SAlex Richardson 			string = get_string(pid, straddr, 0);
1744890843c1SJohn Baldwin 			fprintf(fp, "%s \"%s\"", first ? "" : ",", string);
1745890843c1SJohn Baldwin 			free(string);
1746890843c1SJohn Baldwin 			first = 0;
1747890843c1SJohn Baldwin 
1748890843c1SJohn Baldwin 			i++;
17497daca4e2SAlex Richardson 			if (i == len / pointer_size) {
1750890843c1SJohn Baldwin 				addr += len;
1751890843c1SJohn Baldwin 				len = PAGE_SIZE;
17527daca4e2SAlex Richardson 				if (get_struct(pid, addr, u.buf, len) == -1) {
1753890843c1SJohn Baldwin 					fprintf(fp, ", <inval>");
1754890843c1SJohn Baldwin 					break;
1755890843c1SJohn Baldwin 				}
1756890843c1SJohn Baldwin 				i = 0;
1757890843c1SJohn Baldwin 			}
1758890843c1SJohn Baldwin 		}
1759890843c1SJohn Baldwin 		fputs(" ]", fp);
17609897b203SMatthew N. Dodd 		break;
1761d8984f48SDag-Erling Smørgrav 	}
176272df19e7SJohn Baldwin 	case Quad:
176372df19e7SJohn Baldwin 	case QuadHex: {
17648ba2e89eSAlex Richardson 		uint64_t value;
17658ba2e89eSAlex Richardson 		size_t pointer_size =
17668ba2e89eSAlex Richardson 		    trussinfo->curthread->proc->abi->pointer_size;
17674e3da534SJohn Baldwin 
17688ba2e89eSAlex Richardson 		if (pointer_size == 4) {
17692b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
17708ba2e89eSAlex Richardson 			value = (uint64_t)args[sc->offset + 1] << 32 |
17712b75c8adSJohn Baldwin 			    args[sc->offset];
17722b75c8adSJohn Baldwin #else
17738ba2e89eSAlex Richardson 			value = (uint64_t)args[sc->offset] << 32 |
17742b75c8adSJohn Baldwin 			    args[sc->offset + 1];
17752b75c8adSJohn Baldwin #endif
17768ba2e89eSAlex Richardson 		} else {
17778ba2e89eSAlex Richardson 			value = (uint64_t)args[sc->offset];
17788ba2e89eSAlex Richardson 		}
177972df19e7SJohn Baldwin 		if ((sc->type & ARG_MASK) == Quad)
17808ba2e89eSAlex Richardson 			fprintf(fp, "%jd", (intmax_t)value);
178172df19e7SJohn Baldwin 		else
17828ba2e89eSAlex Richardson 			fprintf(fp, "0x%jx", (intmax_t)value);
1783bbeaf6c0SSean Eric Fagan 		break;
1784bbeaf6c0SSean Eric Fagan 	}
1785b60a095bSJohn Baldwin 	case PQuadHex: {
1786b60a095bSJohn Baldwin 		uint64_t val;
1787b60a095bSJohn Baldwin 
1788cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &val,
1789b60a095bSJohn Baldwin 		    sizeof(val)) == 0)
1790b60a095bSJohn Baldwin 			fprintf(fp, "{ 0x%jx }", (uintmax_t)val);
1791b60a095bSJohn Baldwin 		else
1792cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1793b60a095bSJohn Baldwin 		break;
1794b60a095bSJohn Baldwin 	}
1795bbeaf6c0SSean Eric Fagan 	case Ptr:
1796cc86d14aSBrooks Davis 		print_pointer(fp, args[sc->offset]);
1797bbeaf6c0SSean Eric Fagan 		break;
1798d8984f48SDag-Erling Smørgrav 	case Readlinkres: {
17992bae4eb3SAlfred Perlstein 		char *tmp2;
18004e3da534SJohn Baldwin 
18012b75c8adSJohn Baldwin 		if (retval[0] == -1)
18022bae4eb3SAlfred Perlstein 			break;
1803cc86d14aSBrooks Davis 		tmp2 = get_string(pid, args[sc->offset], retval[0]);
1804f083f689SJohn Baldwin 		fprintf(fp, "\"%s\"", tmp2);
18052bae4eb3SAlfred Perlstein 		free(tmp2);
18062bae4eb3SAlfred Perlstein 		break;
1807d8984f48SDag-Erling Smørgrav 	}
1808d8984f48SDag-Erling Smørgrav 	case Ioctl: {
18094e3da534SJohn Baldwin 		const char *temp;
18104e3da534SJohn Baldwin 		unsigned long cmd;
18114e3da534SJohn Baldwin 
18124e3da534SJohn Baldwin 		cmd = args[sc->offset];
1813265e5898SJohn Baldwin 		temp = sysdecode_ioctlname(cmd);
181494355cfdSAndrey Zonov 		if (temp)
1815f083f689SJohn Baldwin 			fputs(temp, fp);
181694355cfdSAndrey Zonov 		else {
1817f083f689SJohn Baldwin 			fprintf(fp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
18184e3da534SJohn Baldwin 			    cmd, cmd & IOC_OUT ? "R" : "",
18194e3da534SJohn Baldwin 			    cmd & IOC_IN ? "W" : "", IOCGROUP(cmd),
18204e3da534SJohn Baldwin 			    isprint(IOCGROUP(cmd)) ? (char)IOCGROUP(cmd) : '?',
18214e3da534SJohn Baldwin 			    cmd & 0xFF, IOCPARM_LEN(cmd));
1822081e5c48SPav Lucistnik 		}
1823081e5c48SPav Lucistnik 		break;
1824d8984f48SDag-Erling Smørgrav 	}
1825d8984f48SDag-Erling Smørgrav 	case Timespec: {
1826e45a5a0dSDavid Malone 		struct timespec ts;
18274e3da534SJohn Baldwin 
1828cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &ts, sizeof(ts)) != -1)
1829a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%09ld }", (intmax_t)ts.tv_sec,
183094355cfdSAndrey Zonov 			    ts.tv_nsec);
1831e45a5a0dSDavid Malone 		else
1832cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1833e45a5a0dSDavid Malone 		break;
1834d8984f48SDag-Erling Smørgrav 	}
18357d897327SJohn Baldwin 	case Timespec2: {
18367d897327SJohn Baldwin 		struct timespec ts[2];
18377d897327SJohn Baldwin 		const char *sep;
18387d897327SJohn Baldwin 		unsigned int i;
18397d897327SJohn Baldwin 
1840cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &ts, sizeof(ts)) != -1) {
18411e2ec671SJohn Baldwin 			fputs("{ ", fp);
18427d897327SJohn Baldwin 			sep = "";
18437d897327SJohn Baldwin 			for (i = 0; i < nitems(ts); i++) {
18447d897327SJohn Baldwin 				fputs(sep, fp);
18457d897327SJohn Baldwin 				sep = ", ";
18467d897327SJohn Baldwin 				switch (ts[i].tv_nsec) {
18477d897327SJohn Baldwin 				case UTIME_NOW:
18487d897327SJohn Baldwin 					fprintf(fp, "UTIME_NOW");
18497d897327SJohn Baldwin 					break;
18507d897327SJohn Baldwin 				case UTIME_OMIT:
18517d897327SJohn Baldwin 					fprintf(fp, "UTIME_OMIT");
18527d897327SJohn Baldwin 					break;
18537d897327SJohn Baldwin 				default:
1854a1436773SJohn Baldwin 					fprintf(fp, "%jd.%09ld",
1855a1436773SJohn Baldwin 					    (intmax_t)ts[i].tv_sec,
1856a1436773SJohn Baldwin 					    ts[i].tv_nsec);
18577d897327SJohn Baldwin 					break;
18587d897327SJohn Baldwin 				}
18597d897327SJohn Baldwin 			}
18601e2ec671SJohn Baldwin 			fputs(" }", fp);
18617d897327SJohn Baldwin 		} else
1862cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
18637d897327SJohn Baldwin 		break;
18647d897327SJohn Baldwin 	}
1865d8984f48SDag-Erling Smørgrav 	case Timeval: {
1866e45a5a0dSDavid Malone 		struct timeval tv;
18674e3da534SJohn Baldwin 
1868cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &tv, sizeof(tv)) != -1)
1869a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld }", (intmax_t)tv.tv_sec,
187094355cfdSAndrey Zonov 			    tv.tv_usec);
1871081e5c48SPav Lucistnik 		else
1872cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1873081e5c48SPav Lucistnik 		break;
1874d8984f48SDag-Erling Smørgrav 	}
1875d8984f48SDag-Erling Smørgrav 	case Timeval2: {
1876081e5c48SPav Lucistnik 		struct timeval tv[2];
18774e3da534SJohn Baldwin 
1878cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &tv, sizeof(tv)) != -1)
1879a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1880a1436773SJohn Baldwin 			    (intmax_t)tv[0].tv_sec, tv[0].tv_usec,
1881a1436773SJohn Baldwin 			    (intmax_t)tv[1].tv_sec, tv[1].tv_usec);
1882e45a5a0dSDavid Malone 		else
1883cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1884e45a5a0dSDavid Malone 		break;
1885d8984f48SDag-Erling Smørgrav 	}
1886d8984f48SDag-Erling Smørgrav 	case Itimerval: {
1887e45a5a0dSDavid Malone 		struct itimerval itv;
18884e3da534SJohn Baldwin 
1889cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &itv, sizeof(itv)) != -1)
1890a1436773SJohn Baldwin 			fprintf(fp, "{ %jd.%06ld, %jd.%06ld }",
1891a1436773SJohn Baldwin 			    (intmax_t)itv.it_interval.tv_sec,
1892081e5c48SPav Lucistnik 			    itv.it_interval.tv_usec,
1893a1436773SJohn Baldwin 			    (intmax_t)itv.it_value.tv_sec,
1894081e5c48SPav Lucistnik 			    itv.it_value.tv_usec);
1895e45a5a0dSDavid Malone 		else
1896cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1897e45a5a0dSDavid Malone 		break;
1898d8984f48SDag-Erling Smørgrav 	}
18991c99a22aSSteven Hartland 	case LinuxSockArgs:
19001c99a22aSSteven Hartland 	{
19011c99a22aSSteven Hartland 		struct linux_socketcall_args largs;
19024e3da534SJohn Baldwin 
1903cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], (void *)&largs,
1904fb7eabb0SJohn Baldwin 		    sizeof(largs)) != -1)
1905f083f689SJohn Baldwin 			fprintf(fp, "{ %s, 0x%lx }",
1906fb7eabb0SJohn Baldwin 			    lookup(linux_socketcall_ops, largs.what, 10),
19070a46af44SJohn Baldwin 			    (long unsigned int)largs.args);
1908fb7eabb0SJohn Baldwin 		else
1909cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
19101c99a22aSSteven Hartland 		break;
19111c99a22aSSteven Hartland 	}
1912d8984f48SDag-Erling Smørgrav 	case Pollfd: {
1913e45a5a0dSDavid Malone 		/*
191494355cfdSAndrey Zonov 		 * XXX: A Pollfd argument expects the /next/ syscall argument
191594355cfdSAndrey Zonov 		 * to be the number of fds in the array. This matches the poll
191694355cfdSAndrey Zonov 		 * syscall.
1917e45a5a0dSDavid Malone 		 */
1918e45a5a0dSDavid Malone 		struct pollfd *pfd;
1919e45a5a0dSDavid Malone 		int numfds = args[sc->offset + 1];
1920f083f689SJohn Baldwin 		size_t bytes = sizeof(struct pollfd) * numfds;
1921f083f689SJohn Baldwin 		int i;
1922e45a5a0dSDavid Malone 
1923e45a5a0dSDavid Malone 		if ((pfd = malloc(bytes)) == NULL)
1924f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for pollfd array",
192594355cfdSAndrey Zonov 			    bytes);
1926cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], pfd, bytes) != -1) {
1927f083f689SJohn Baldwin 			fputs("{", fp);
1928e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1929f083f689SJohn Baldwin 				fprintf(fp, " %d/%s", pfd[i].fd,
1930081e5c48SPav Lucistnik 				    xlookup_bits(poll_flags, pfd[i].events));
1931e45a5a0dSDavid Malone 			}
1932f083f689SJohn Baldwin 			fputs(" }", fp);
1933d8984f48SDag-Erling Smørgrav 		} else {
1934cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1935e45a5a0dSDavid Malone 		}
1936d8984f48SDag-Erling Smørgrav 		free(pfd);
1937e45a5a0dSDavid Malone 		break;
1938d8984f48SDag-Erling Smørgrav 	}
1939d8984f48SDag-Erling Smørgrav 	case Fd_set: {
1940e45a5a0dSDavid Malone 		/*
194194355cfdSAndrey Zonov 		 * XXX: A Fd_set argument expects the /first/ syscall argument
194294355cfdSAndrey Zonov 		 * to be the number of fds in the array.  This matches the
194394355cfdSAndrey Zonov 		 * select syscall.
1944e45a5a0dSDavid Malone 		 */
1945e45a5a0dSDavid Malone 		fd_set *fds;
1946e45a5a0dSDavid Malone 		int numfds = args[0];
1947f083f689SJohn Baldwin 		size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
1948f083f689SJohn Baldwin 		int i;
1949e45a5a0dSDavid Malone 
1950e45a5a0dSDavid Malone 		if ((fds = malloc(bytes)) == NULL)
1951f083f689SJohn Baldwin 			err(1, "Cannot malloc %zu bytes for fd_set array",
195294355cfdSAndrey Zonov 			    bytes);
1953cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], fds, bytes) != -1) {
1954f083f689SJohn Baldwin 			fputs("{", fp);
1955e45a5a0dSDavid Malone 			for (i = 0; i < numfds; i++) {
1956f083f689SJohn Baldwin 				if (FD_ISSET(i, fds))
1957f083f689SJohn Baldwin 					fprintf(fp, " %d", i);
1958e45a5a0dSDavid Malone 			}
1959f083f689SJohn Baldwin 			fputs(" }", fp);
196094355cfdSAndrey Zonov 		} else
1961cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1962d8984f48SDag-Erling Smørgrav 		free(fds);
1963e45a5a0dSDavid Malone 		break;
1964d8984f48SDag-Erling Smørgrav 	}
196534763d1cSJohn Baldwin 	case Signal:
1966f083f689SJohn Baldwin 		fputs(strsig2(args[sc->offset]), fp);
1967f0ebbc29SDag-Erling Smørgrav 		break;
1968d8984f48SDag-Erling Smørgrav 	case Sigset: {
1969081e5c48SPav Lucistnik 		sigset_t ss;
1970f083f689SJohn Baldwin 		int i, first;
1971081e5c48SPav Lucistnik 
1972cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], (void *)&ss,
197394355cfdSAndrey Zonov 		    sizeof(ss)) == -1) {
1974cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
1975081e5c48SPav Lucistnik 			break;
1976081e5c48SPav Lucistnik 		}
1977f083f689SJohn Baldwin 		fputs("{ ", fp);
1978f083f689SJohn Baldwin 		first = 1;
1979d8984f48SDag-Erling Smørgrav 		for (i = 1; i < sys_nsig; i++) {
198034763d1cSJohn Baldwin 			if (sigismember(&ss, i)) {
1981f083f689SJohn Baldwin 				fprintf(fp, "%s%s", !first ? "|" : "",
19829289f547SJohn Baldwin 				    strsig2(i));
1983f083f689SJohn Baldwin 				first = 0;
198434763d1cSJohn Baldwin 			}
1985081e5c48SPav Lucistnik 		}
1986f083f689SJohn Baldwin 		if (!first)
1987f083f689SJohn Baldwin 			fputc(' ', fp);
1988f083f689SJohn Baldwin 		fputc('}', fp);
1989081e5c48SPav Lucistnik 		break;
1990d8984f48SDag-Erling Smørgrav 	}
19919289f547SJohn Baldwin 	case Sigprocmask:
19929289f547SJohn Baldwin 		print_integer_arg(sysdecode_sigprocmask_how, fp,
19939289f547SJohn Baldwin 		    args[sc->offset]);
1994894b8f7aSAlfred Perlstein 		break;
19959289f547SJohn Baldwin 	case Fcntlflag:
19964e3da534SJohn Baldwin 		/* XXX: Output depends on the value of the previous argument. */
19979289f547SJohn Baldwin 		if (sysdecode_fcntl_arg_p(args[sc->offset - 1]))
19989289f547SJohn Baldwin 			sysdecode_fcntl_arg(fp, args[sc->offset - 1],
19999289f547SJohn Baldwin 			    args[sc->offset], 16);
2000081e5c48SPav Lucistnik 		break;
2001081e5c48SPav Lucistnik 	case Open:
20029289f547SJohn Baldwin 		print_mask_arg(sysdecode_open_flags, fp, args[sc->offset]);
2003081e5c48SPav Lucistnik 		break;
2004081e5c48SPav Lucistnik 	case Fcntl:
20059289f547SJohn Baldwin 		print_integer_arg(sysdecode_fcntl_cmd, fp, args[sc->offset]);
2006081e5c48SPav Lucistnik 		break;
2007f3f3e3c4SMateusz Guzik 	case Closerangeflags:
2008f3f3e3c4SMateusz Guzik 		print_mask_arg(sysdecode_close_range_flags, fp, args[sc->offset]);
2009f3f3e3c4SMateusz Guzik 		break;
2010894b8f7aSAlfred Perlstein 	case Mprot:
20119289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_prot, fp, args[sc->offset]);
2012894b8f7aSAlfred Perlstein 		break;
20139289f547SJohn Baldwin 	case Mmapflags:
20149289f547SJohn Baldwin 		print_mask_arg(sysdecode_mmap_flags, fp, args[sc->offset]);
2015894b8f7aSAlfred Perlstein 		break;
2016fde3a7d1SAlfred Perlstein 	case Whence:
20179289f547SJohn Baldwin 		print_integer_arg(sysdecode_whence, fp, args[sc->offset]);
2018081e5c48SPav Lucistnik 		break;
2019bcca3425SKyle Evans 	case ShmFlags:
2020bcca3425SKyle Evans 		print_mask_arg(sysdecode_shmflags, fp, args[sc->offset]);
2021bcca3425SKyle Evans 		break;
2022081e5c48SPav Lucistnik 	case Sockdomain:
20239289f547SJohn Baldwin 		print_integer_arg(sysdecode_socketdomain, fp, args[sc->offset]);
2024081e5c48SPav Lucistnik 		break;
20259289f547SJohn Baldwin 	case Socktype:
20269289f547SJohn Baldwin 		print_mask_arg(sysdecode_socket_type, fp, args[sc->offset]);
2027081e5c48SPav Lucistnik 		break;
2028081e5c48SPav Lucistnik 	case Shutdown:
20299289f547SJohn Baldwin 		print_integer_arg(sysdecode_shutdown_how, fp, args[sc->offset]);
2030081e5c48SPav Lucistnik 		break;
2031081e5c48SPav Lucistnik 	case Resource:
20329289f547SJohn Baldwin 		print_integer_arg(sysdecode_rlimit, fp, args[sc->offset]);
2033081e5c48SPav Lucistnik 		break;
2034ee8aa41dSJohn Baldwin 	case RusageWho:
2035ee8aa41dSJohn Baldwin 		print_integer_arg(sysdecode_getrusage_who, fp, args[sc->offset]);
2036ee8aa41dSJohn Baldwin 		break;
2037081e5c48SPav Lucistnik 	case Pathconf:
203839a3a438SJohn Baldwin 		print_integer_arg(sysdecode_pathconf_name, fp, args[sc->offset]);
2039fde3a7d1SAlfred Perlstein 		break;
20409e1db66eSMark Johnston 	case Rforkflags:
20419289f547SJohn Baldwin 		print_mask_arg(sysdecode_rfork_flags, fp, args[sc->offset]);
20429e1db66eSMark Johnston 		break;
2043d8984f48SDag-Erling Smørgrav 	case Sockaddr: {
204466917ca9SJohn Baldwin 		socklen_t len;
20459ddd1412SDag-Erling Smørgrav 
2046a7a08c7eSMarcel Moolenaar 		if (args[sc->offset] == 0) {
2047f083f689SJohn Baldwin 			fputs("NULL", fp);
2048a7a08c7eSMarcel Moolenaar 			break;
2049a7a08c7eSMarcel Moolenaar 		}
2050a7a08c7eSMarcel Moolenaar 
20516a656761SAlfred Perlstein 		/*
205266917ca9SJohn Baldwin 		 * Extract the address length from the next argument.  If
205366917ca9SJohn Baldwin 		 * this is an output sockaddr (OUT is set), then the
205466917ca9SJohn Baldwin 		 * next argument is a pointer to a socklen_t.  Otherwise
205566917ca9SJohn Baldwin 		 * the next argument contains a socklen_t by value.
20566a656761SAlfred Perlstein 		 */
205766917ca9SJohn Baldwin 		if (sc->type & OUT) {
2058cc86d14aSBrooks Davis 			if (get_struct(pid, args[sc->offset + 1], &len,
2059cc86d14aSBrooks Davis 			    sizeof(len)) == -1) {
2060cc86d14aSBrooks Davis 				print_pointer(fp, args[sc->offset]);
20616a656761SAlfred Perlstein 				break;
20626a656761SAlfred Perlstein 			}
206366917ca9SJohn Baldwin 		} else
206466917ca9SJohn Baldwin 			len = args[sc->offset + 1];
206566917ca9SJohn Baldwin 
2066cc86d14aSBrooks Davis 		print_sockaddr(fp, trussinfo, args[sc->offset], len);
20679ddd1412SDag-Erling Smørgrav 		break;
2068d8984f48SDag-Erling Smørgrav 	}
2069d8984f48SDag-Erling Smørgrav 	case Sigaction: {
2070e45a5a0dSDavid Malone 		struct sigaction sa;
2071e45a5a0dSDavid Malone 
2072cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &sa, sizeof(sa)) != -1) {
2073f083f689SJohn Baldwin 			fputs("{ ", fp);
2074e45a5a0dSDavid Malone 			if (sa.sa_handler == SIG_DFL)
2075f083f689SJohn Baldwin 				fputs("SIG_DFL", fp);
2076e45a5a0dSDavid Malone 			else if (sa.sa_handler == SIG_IGN)
2077f083f689SJohn Baldwin 				fputs("SIG_IGN", fp);
2078e45a5a0dSDavid Malone 			else
2079f083f689SJohn Baldwin 				fprintf(fp, "%p", sa.sa_handler);
2080f083f689SJohn Baldwin 			fprintf(fp, " %s ss_t }",
2081081e5c48SPav Lucistnik 			    xlookup_bits(sigaction_flags, sa.sa_flags));
208294355cfdSAndrey Zonov 		} else
2083cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2084e45a5a0dSDavid Malone 		break;
2085d8984f48SDag-Erling Smørgrav 	}
2086bb24ee2bSThomas Munro 	case Sigevent: {
2087bb24ee2bSThomas Munro 		struct sigevent se;
2088bb24ee2bSThomas Munro 
2089bb24ee2bSThomas Munro 		if (get_struct(pid, args[sc->offset], &se, sizeof(se)) != -1)
2090bb24ee2bSThomas Munro 			print_sigevent(fp, &se);
2091bb24ee2bSThomas Munro 		else
2092bb24ee2bSThomas Munro 			print_pointer(fp, args[sc->offset]);
2093bb24ee2bSThomas Munro 		break;
2094bb24ee2bSThomas Munro 	}
2095d8984f48SDag-Erling Smørgrav 	case Kevent: {
2096081e5c48SPav Lucistnik 		/*
20974e3da534SJohn Baldwin 		 * XXX XXX: The size of the array is determined by either the
2098081e5c48SPav Lucistnik 		 * next syscall argument, or by the syscall return value,
2099081e5c48SPav Lucistnik 		 * depending on which argument number we are.  This matches the
2100081e5c48SPav Lucistnik 		 * kevent syscall, but luckily that's the only syscall that uses
2101081e5c48SPav Lucistnik 		 * them.
2102081e5c48SPav Lucistnik 		 */
2103081e5c48SPav Lucistnik 		struct kevent *ke;
2104081e5c48SPav Lucistnik 		int numevents = -1;
2105f083f689SJohn Baldwin 		size_t bytes;
2106f083f689SJohn Baldwin 		int i;
2107081e5c48SPav Lucistnik 
2108081e5c48SPav Lucistnik 		if (sc->offset == 1)
2109081e5c48SPav Lucistnik 			numevents = args[sc->offset+1];
21102b75c8adSJohn Baldwin 		else if (sc->offset == 3 && retval[0] != -1)
21112b75c8adSJohn Baldwin 			numevents = retval[0];
2112081e5c48SPav Lucistnik 
2113f083f689SJohn Baldwin 		if (numevents >= 0) {
2114081e5c48SPav Lucistnik 			bytes = sizeof(struct kevent) * numevents;
2115081e5c48SPav Lucistnik 			if ((ke = malloc(bytes)) == NULL)
2116f083f689SJohn Baldwin 				err(1,
2117f083f689SJohn Baldwin 				    "Cannot malloc %zu bytes for kevent array",
211894355cfdSAndrey Zonov 				    bytes);
2119f083f689SJohn Baldwin 		} else
2120f083f689SJohn Baldwin 			ke = NULL;
2121cc86d14aSBrooks Davis 		if (numevents >= 0 && get_struct(pid, args[sc->offset],
212294355cfdSAndrey Zonov 		    ke, bytes) != -1) {
2123f083f689SJohn Baldwin 			fputc('{', fp);
2124c915ff03SJohn Baldwin 			for (i = 0; i < numevents; i++) {
2125c915ff03SJohn Baldwin 				fputc(' ', fp);
2126ffb66079SJohn Baldwin 				print_kevent(fp, &ke[i]);
2127c915ff03SJohn Baldwin 			}
2128f083f689SJohn Baldwin 			fputs(" }", fp);
2129d8984f48SDag-Erling Smørgrav 		} else {
2130cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2131081e5c48SPav Lucistnik 		}
2132d8984f48SDag-Erling Smørgrav 		free(ke);
2133081e5c48SPav Lucistnik 		break;
2134d8984f48SDag-Erling Smørgrav 	}
2135ffb66079SJohn Baldwin 	case Kevent11: {
21368e4a3addSBrooks Davis 		struct freebsd11_kevent *ke11;
2137ffb66079SJohn Baldwin 		struct kevent ke;
2138ffb66079SJohn Baldwin 		int numevents = -1;
2139ffb66079SJohn Baldwin 		size_t bytes;
2140ffb66079SJohn Baldwin 		int i;
2141ffb66079SJohn Baldwin 
2142ffb66079SJohn Baldwin 		if (sc->offset == 1)
2143ffb66079SJohn Baldwin 			numevents = args[sc->offset+1];
2144ffb66079SJohn Baldwin 		else if (sc->offset == 3 && retval[0] != -1)
2145ffb66079SJohn Baldwin 			numevents = retval[0];
2146ffb66079SJohn Baldwin 
2147ffb66079SJohn Baldwin 		if (numevents >= 0) {
21488e4a3addSBrooks Davis 			bytes = sizeof(struct freebsd11_kevent) * numevents;
2149ffb66079SJohn Baldwin 			if ((ke11 = malloc(bytes)) == NULL)
2150ffb66079SJohn Baldwin 				err(1,
2151ffb66079SJohn Baldwin 				    "Cannot malloc %zu bytes for kevent array",
2152ffb66079SJohn Baldwin 				    bytes);
2153ffb66079SJohn Baldwin 		} else
2154ffb66079SJohn Baldwin 			ke11 = NULL;
2155ffb66079SJohn Baldwin 		memset(&ke, 0, sizeof(ke));
2156cc86d14aSBrooks Davis 		if (numevents >= 0 && get_struct(pid, args[sc->offset],
2157ffb66079SJohn Baldwin 		    ke11, bytes) != -1) {
2158ffb66079SJohn Baldwin 			fputc('{', fp);
2159ffb66079SJohn Baldwin 			for (i = 0; i < numevents; i++) {
2160ffb66079SJohn Baldwin 				fputc(' ', fp);
2161ffb66079SJohn Baldwin 				ke.ident = ke11[i].ident;
2162ffb66079SJohn Baldwin 				ke.filter = ke11[i].filter;
2163ffb66079SJohn Baldwin 				ke.flags = ke11[i].flags;
2164ffb66079SJohn Baldwin 				ke.fflags = ke11[i].fflags;
2165ffb66079SJohn Baldwin 				ke.data = ke11[i].data;
2166ffb66079SJohn Baldwin 				ke.udata = ke11[i].udata;
2167ffb66079SJohn Baldwin 				print_kevent(fp, &ke);
2168ffb66079SJohn Baldwin 			}
2169ffb66079SJohn Baldwin 			fputs(" }", fp);
2170ffb66079SJohn Baldwin 		} else {
2171cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2172ffb66079SJohn Baldwin 		}
2173ffb66079SJohn Baldwin 		free(ke11);
2174ffb66079SJohn Baldwin 		break;
2175ffb66079SJohn Baldwin 	}
2176d8984f48SDag-Erling Smørgrav 	case Stat: {
2177081e5c48SPav Lucistnik 		struct stat st;
21784e3da534SJohn Baldwin 
2179cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &st, sizeof(st))
218094355cfdSAndrey Zonov 		    != -1) {
2181081e5c48SPav Lucistnik 			char mode[12];
21824e3da534SJohn Baldwin 
2183081e5c48SPav Lucistnik 			strmode(st.st_mode, mode);
2184f083f689SJohn Baldwin 			fprintf(fp,
2185b38fbc2eSJohn Baldwin 			    "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode,
2186b38fbc2eSJohn Baldwin 			    (uintmax_t)st.st_ino, (intmax_t)st.st_size,
218794355cfdSAndrey Zonov 			    (long)st.st_blksize);
2188d8984f48SDag-Erling Smørgrav 		} else {
2189cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2190081e5c48SPav Lucistnik 		}
2191081e5c48SPav Lucistnik 		break;
2192d8984f48SDag-Erling Smørgrav 	}
21938207f12dSWarner Losh 	case Stat11: {
21948207f12dSWarner Losh 		struct freebsd11_stat st;
21958207f12dSWarner Losh 
2196cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &st, sizeof(st))
21978207f12dSWarner Losh 		    != -1) {
21988207f12dSWarner Losh 			char mode[12];
21998207f12dSWarner Losh 
22008207f12dSWarner Losh 			strmode(st.st_mode, mode);
22018207f12dSWarner Losh 			fprintf(fp,
22028207f12dSWarner Losh 			    "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode,
22038207f12dSWarner Losh 			    (uintmax_t)st.st_ino, (intmax_t)st.st_size,
22048207f12dSWarner Losh 			    (long)st.st_blksize);
22058207f12dSWarner Losh 		} else {
2206cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
22078207f12dSWarner Losh 		}
22088207f12dSWarner Losh 		break;
22098207f12dSWarner Losh 	}
2210a776866bSBryan Drewery 	case StatFs: {
2211a776866bSBryan Drewery 		unsigned int i;
2212a776866bSBryan Drewery 		struct statfs buf;
22130a71c082SBryan Drewery 
2214cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &buf,
2215a776866bSBryan Drewery 		    sizeof(buf)) != -1) {
2216a776866bSBryan Drewery 			char fsid[17];
2217a776866bSBryan Drewery 
2218a776866bSBryan Drewery 			bzero(fsid, sizeof(fsid));
2219a776866bSBryan Drewery 			if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) {
2220a776866bSBryan Drewery 			        for (i = 0; i < sizeof(buf.f_fsid); i++)
2221a776866bSBryan Drewery 					snprintf(&fsid[i*2],
2222a776866bSBryan Drewery 					    sizeof(fsid) - (i*2), "%02x",
2223a776866bSBryan Drewery 					    ((u_char *)&buf.f_fsid)[i]);
2224a776866bSBryan Drewery 			}
2225a776866bSBryan Drewery 			fprintf(fp,
2226a776866bSBryan Drewery 			    "{ fstypename=%s,mntonname=%s,mntfromname=%s,"
2227a776866bSBryan Drewery 			    "fsid=%s }", buf.f_fstypename, buf.f_mntonname,
2228a776866bSBryan Drewery 			    buf.f_mntfromname, fsid);
2229a776866bSBryan Drewery 		} else
2230cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2231a776866bSBryan Drewery 		break;
2232a776866bSBryan Drewery 	}
2233a776866bSBryan Drewery 
2234d8984f48SDag-Erling Smørgrav 	case Rusage: {
2235081e5c48SPav Lucistnik 		struct rusage ru;
22364e3da534SJohn Baldwin 
2237cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &ru, sizeof(ru))
223894355cfdSAndrey Zonov 		    != -1) {
2239f083f689SJohn Baldwin 			fprintf(fp,
2240a1436773SJohn Baldwin 			    "{ u=%jd.%06ld,s=%jd.%06ld,in=%ld,out=%ld }",
2241a1436773SJohn Baldwin 			    (intmax_t)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
2242a1436773SJohn Baldwin 			    (intmax_t)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
2243081e5c48SPav Lucistnik 			    ru.ru_inblock, ru.ru_oublock);
224494355cfdSAndrey Zonov 		} else
2245cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2246081e5c48SPav Lucistnik 		break;
2247d8984f48SDag-Erling Smørgrav 	}
2248d8984f48SDag-Erling Smørgrav 	case Rlimit: {
2249081e5c48SPav Lucistnik 		struct rlimit rl;
22504e3da534SJohn Baldwin 
2251cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &rl, sizeof(rl))
225294355cfdSAndrey Zonov 		    != -1) {
2253f083f689SJohn Baldwin 			fprintf(fp, "{ cur=%ju,max=%ju }",
2254081e5c48SPav Lucistnik 			    rl.rlim_cur, rl.rlim_max);
225594355cfdSAndrey Zonov 		} else
2256cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2257081e5c48SPav Lucistnik 		break;
2258d8984f48SDag-Erling Smørgrav 	}
225934763d1cSJohn Baldwin 	case ExitStatus: {
226034763d1cSJohn Baldwin 		int status;
2261f083f689SJohn Baldwin 
2262cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &status,
226334763d1cSJohn Baldwin 		    sizeof(status)) != -1) {
2264f083f689SJohn Baldwin 			fputs("{ ", fp);
226534763d1cSJohn Baldwin 			if (WIFCONTINUED(status))
2266f083f689SJohn Baldwin 				fputs("CONTINUED", fp);
226734763d1cSJohn Baldwin 			else if (WIFEXITED(status))
2268f083f689SJohn Baldwin 				fprintf(fp, "EXITED,val=%d",
226934763d1cSJohn Baldwin 				    WEXITSTATUS(status));
227034763d1cSJohn Baldwin 			else if (WIFSIGNALED(status))
2271f083f689SJohn Baldwin 				fprintf(fp, "SIGNALED,sig=%s%s",
2272f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)),
227334763d1cSJohn Baldwin 				    WCOREDUMP(status) ? ",cored" : "");
227434763d1cSJohn Baldwin 			else
2275f083f689SJohn Baldwin 				fprintf(fp, "STOPPED,sig=%s",
2276f083f689SJohn Baldwin 				    strsig2(WTERMSIG(status)));
2277f083f689SJohn Baldwin 			fputs(" }", fp);
227834763d1cSJohn Baldwin 		} else
2279cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
228034763d1cSJohn Baldwin 		break;
228134763d1cSJohn Baldwin 	}
228234763d1cSJohn Baldwin 	case Waitoptions:
22839289f547SJohn Baldwin 		print_mask_arg(sysdecode_wait6_options, fp, args[sc->offset]);
228434763d1cSJohn Baldwin 		break;
228534763d1cSJohn Baldwin 	case Idtype:
22869289f547SJohn Baldwin 		print_integer_arg(sysdecode_idtype, fp, args[sc->offset]);
228734763d1cSJohn Baldwin 		break;
228855648840SJohn Baldwin 	case Procctl:
22899289f547SJohn Baldwin 		print_integer_arg(sysdecode_procctl_cmd, fp, args[sc->offset]);
229055648840SJohn Baldwin 		break;
2291c2679dd7SKyle Evans 	case Umtxop: {
2292c2679dd7SKyle Evans 		int rem;
2293c2679dd7SKyle Evans 
2294c2679dd7SKyle Evans 		if (print_mask_arg_part(sysdecode_umtx_op_flags, fp,
2295c2679dd7SKyle Evans 		    args[sc->offset], &rem))
2296c2679dd7SKyle Evans 			fprintf(fp, "|");
2297c2679dd7SKyle Evans 		print_integer_arg(sysdecode_umtx_op, fp, rem);
2298fdb5bf37SJohn Baldwin 		break;
2299c2679dd7SKyle Evans 	}
23007d897327SJohn Baldwin 	case Atfd:
23019289f547SJohn Baldwin 		print_integer_arg(sysdecode_atfd, fp, args[sc->offset]);
23027d897327SJohn Baldwin 		break;
23037d897327SJohn Baldwin 	case Atflags:
230439a3a438SJohn Baldwin 		print_mask_arg(sysdecode_atflags, fp, args[sc->offset]);
23057d897327SJohn Baldwin 		break;
23067d897327SJohn Baldwin 	case Accessmode:
23079289f547SJohn Baldwin 		print_mask_arg(sysdecode_access_mode, fp, args[sc->offset]);
23087d897327SJohn Baldwin 		break;
2309b289a8d7SJohn Baldwin 	case Sysarch:
231039a3a438SJohn Baldwin 		print_integer_arg(sysdecode_sysarch_number, fp,
231139a3a438SJohn Baldwin 		    args[sc->offset]);
2312b289a8d7SJohn Baldwin 		break;
231343ce0d90SKonstantin Belousov 	case Sysctl: {
231443ce0d90SKonstantin Belousov 		char name[BUFSIZ];
231543ec732aSPawel Biernacki 		int oid[CTL_MAXNAME + 2];
231643ec732aSPawel Biernacki 		size_t len;
231743ce0d90SKonstantin Belousov 
231843ce0d90SKonstantin Belousov 		memset(name, 0, sizeof(name));
231943ce0d90SKonstantin Belousov 		len = args[sc->offset + 1];
2320cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], oid,
232143ce0d90SKonstantin Belousov 		    len * sizeof(oid[0])) != -1) {
232243ce0d90SKonstantin Belousov 		    	fprintf(fp, "\"");
232343ce0d90SKonstantin Belousov 			if (oid[0] == CTL_SYSCTL) {
232443ce0d90SKonstantin Belousov 				fprintf(fp, "sysctl.");
232543ce0d90SKonstantin Belousov 				switch (oid[1]) {
232643ce0d90SKonstantin Belousov 				case CTL_SYSCTL_DEBUG:
232743ce0d90SKonstantin Belousov 					fprintf(fp, "debug");
232843ce0d90SKonstantin Belousov 					break;
232943ce0d90SKonstantin Belousov 				case CTL_SYSCTL_NAME:
233043ce0d90SKonstantin Belousov 					fprintf(fp, "name ");
233143ce0d90SKonstantin Belousov 					print_sysctl_oid(fp, oid + 2, len - 2);
233243ce0d90SKonstantin Belousov 					break;
233343ce0d90SKonstantin Belousov 				case CTL_SYSCTL_NEXT:
233443ce0d90SKonstantin Belousov 					fprintf(fp, "next");
233543ce0d90SKonstantin Belousov 					break;
233643ce0d90SKonstantin Belousov 				case CTL_SYSCTL_NAME2OID:
233743ec732aSPawel Biernacki 					fprintf(fp, "name2oid %s",
233843ec732aSPawel Biernacki 					    get_string(pid,
233943ec732aSPawel Biernacki 					        args[sc->offset + 4],
234043ec732aSPawel Biernacki 						args[sc->offset + 5]));
234143ce0d90SKonstantin Belousov 					break;
234243ce0d90SKonstantin Belousov 				case CTL_SYSCTL_OIDFMT:
234343ce0d90SKonstantin Belousov 					fprintf(fp, "oidfmt ");
234443ec732aSPawel Biernacki 					print_sysctl(fp, oid + 2, len - 2);
234543ce0d90SKonstantin Belousov 					break;
234643ce0d90SKonstantin Belousov 				case CTL_SYSCTL_OIDDESCR:
234743ce0d90SKonstantin Belousov 					fprintf(fp, "oiddescr ");
234843ec732aSPawel Biernacki 					print_sysctl(fp, oid + 2, len - 2);
234943ce0d90SKonstantin Belousov 					break;
235043ce0d90SKonstantin Belousov 				case CTL_SYSCTL_OIDLABEL:
235143ce0d90SKonstantin Belousov 					fprintf(fp, "oidlabel ");
235243ec732aSPawel Biernacki 					print_sysctl(fp, oid + 2, len - 2);
235343ce0d90SKonstantin Belousov 					break;
235492e17803SRyan Moeller 				case CTL_SYSCTL_NEXTNOSKIP:
235592e17803SRyan Moeller 					fprintf(fp, "nextnoskip");
235692e17803SRyan Moeller 					break;
235743ce0d90SKonstantin Belousov 				default:
235843ec732aSPawel Biernacki 					print_sysctl(fp, oid + 1, len - 1);
235943ce0d90SKonstantin Belousov 				}
236043ce0d90SKonstantin Belousov 			} else {
236143ec732aSPawel Biernacki 				print_sysctl(fp, oid, len);
236243ce0d90SKonstantin Belousov 			}
236343ce0d90SKonstantin Belousov 		    	fprintf(fp, "\"");
236443ce0d90SKonstantin Belousov 		}
236543ce0d90SKonstantin Belousov 		break;
236643ce0d90SKonstantin Belousov 	}
23672b75c8adSJohn Baldwin 	case PipeFds:
23682b75c8adSJohn Baldwin 		/*
23692b75c8adSJohn Baldwin 		 * The pipe() system call in the kernel returns its
23702b75c8adSJohn Baldwin 		 * two file descriptors via return values.  However,
23712b75c8adSJohn Baldwin 		 * the interface exposed by libc is that pipe()
23722b75c8adSJohn Baldwin 		 * accepts a pointer to an array of descriptors.
23732b75c8adSJohn Baldwin 		 * Format the output to match the libc API by printing
23742b75c8adSJohn Baldwin 		 * the returned file descriptors as a fake argument.
23752b75c8adSJohn Baldwin 		 *
23762b75c8adSJohn Baldwin 		 * Overwrite the first retval to signal a successful
23772b75c8adSJohn Baldwin 		 * return as well.
23782b75c8adSJohn Baldwin 		 */
2379caa449b6SJohn Baldwin 		fprintf(fp, "{ %d, %d }", (int)retval[0], (int)retval[1]);
23802b75c8adSJohn Baldwin 		retval[0] = 0;
23812b75c8adSJohn Baldwin 		break;
2382195aef99SBryan Drewery 	case Utrace: {
2383195aef99SBryan Drewery 		size_t len;
2384195aef99SBryan Drewery 		void *utrace_addr;
2385195aef99SBryan Drewery 
2386195aef99SBryan Drewery 		len = args[sc->offset + 1];
2387195aef99SBryan Drewery 		utrace_addr = calloc(1, len);
2388cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset],
2389195aef99SBryan Drewery 		    (void *)utrace_addr, len) != -1)
2390195aef99SBryan Drewery 			print_utrace(fp, utrace_addr, len);
2391195aef99SBryan Drewery 		else
2392cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2393195aef99SBryan Drewery 		free(utrace_addr);
2394195aef99SBryan Drewery 		break;
2395195aef99SBryan Drewery 	}
2396808d9805SEd Schouten 	case IntArray: {
2397808d9805SEd Schouten 		int descriptors[16];
2398808d9805SEd Schouten 		unsigned long i, ndescriptors;
2399808d9805SEd Schouten 		bool truncated;
2400808d9805SEd Schouten 
2401808d9805SEd Schouten 		ndescriptors = args[sc->offset + 1];
2402808d9805SEd Schouten 		truncated = false;
2403808d9805SEd Schouten 		if (ndescriptors > nitems(descriptors)) {
2404808d9805SEd Schouten 			ndescriptors = nitems(descriptors);
2405808d9805SEd Schouten 			truncated = true;
2406808d9805SEd Schouten 		}
2407cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset],
2408808d9805SEd Schouten 		    descriptors, ndescriptors * sizeof(descriptors[0])) != -1) {
2409808d9805SEd Schouten 			fprintf(fp, "{");
2410808d9805SEd Schouten 			for (i = 0; i < ndescriptors; i++)
2411808d9805SEd Schouten 				fprintf(fp, i == 0 ? " %d" : ", %d",
2412808d9805SEd Schouten 				    descriptors[i]);
2413808d9805SEd Schouten 			fprintf(fp, truncated ? ", ... }" : " }");
2414808d9805SEd Schouten 		} else
2415cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2416808d9805SEd Schouten 		break;
2417808d9805SEd Schouten 	}
24189289f547SJohn Baldwin 	case Pipe2:
24199289f547SJohn Baldwin 		print_mask_arg(sysdecode_pipe2_flags, fp, args[sc->offset]);
24209289f547SJohn Baldwin 		break;
2421bed418c8SJohn Baldwin 	case CapFcntlRights: {
2422bed418c8SJohn Baldwin 		uint32_t rights;
2423bed418c8SJohn Baldwin 
2424bed418c8SJohn Baldwin 		if (sc->type & OUT) {
2425cc86d14aSBrooks Davis 			if (get_struct(pid, args[sc->offset], &rights,
2426bed418c8SJohn Baldwin 			    sizeof(rights)) == -1) {
2427cc86d14aSBrooks Davis 				print_pointer(fp, args[sc->offset]);
2428bed418c8SJohn Baldwin 				break;
2429bed418c8SJohn Baldwin 			}
2430bed418c8SJohn Baldwin 		} else
2431bed418c8SJohn Baldwin 			rights = args[sc->offset];
2432bed418c8SJohn Baldwin 		print_mask_arg32(sysdecode_cap_fcntlrights, fp, rights);
2433bed418c8SJohn Baldwin 		break;
2434bed418c8SJohn Baldwin 	}
2435d2a97485SJohn Baldwin 	case Fadvice:
2436d2a97485SJohn Baldwin 		print_integer_arg(sysdecode_fadvice, fp, args[sc->offset]);
2437d2a97485SJohn Baldwin 		break;
243827459358SJohn Baldwin 	case FileFlags: {
243927459358SJohn Baldwin 		fflags_t rem;
244027459358SJohn Baldwin 
244127459358SJohn Baldwin 		if (!sysdecode_fileflags(fp, args[sc->offset], &rem))
244227459358SJohn Baldwin 			fprintf(fp, "0x%x", rem);
244327459358SJohn Baldwin 		else if (rem != 0)
244427459358SJohn Baldwin 			fprintf(fp, "|0x%x", rem);
244527459358SJohn Baldwin 		break;
244627459358SJohn Baldwin 	}
2447dd92181fSJohn Baldwin 	case Flockop:
2448dd92181fSJohn Baldwin 		print_mask_arg(sysdecode_flock_operation, fp, args[sc->offset]);
2449dd92181fSJohn Baldwin 		break;
2450ab43bedcSJohn Baldwin 	case Getfsstatmode:
2451ab43bedcSJohn Baldwin 		print_integer_arg(sysdecode_getfsstat_mode, fp,
2452ab43bedcSJohn Baldwin 		    args[sc->offset]);
2453ab43bedcSJohn Baldwin 		break;
2454*b9b86b67SDmitry Chagin 	case Itimerwhich:
2455*b9b86b67SDmitry Chagin 		print_integer_arg(sysdecode_itimer, fp, args[sc->offset]);
2456*b9b86b67SDmitry Chagin 		break;
245794e854c5SJohn Baldwin 	case Kldsymcmd:
245894e854c5SJohn Baldwin 		print_integer_arg(sysdecode_kldsym_cmd, fp, args[sc->offset]);
245994e854c5SJohn Baldwin 		break;
246094e854c5SJohn Baldwin 	case Kldunloadflags:
246194e854c5SJohn Baldwin 		print_integer_arg(sysdecode_kldunload_flags, fp,
246294e854c5SJohn Baldwin 		    args[sc->offset]);
246394e854c5SJohn Baldwin 		break;
2464bb24ee2bSThomas Munro 	case AiofsyncOp:
2465bb24ee2bSThomas Munro 		fputs(xlookup(aio_fsync_ops, args[sc->offset]), fp);
2466bb24ee2bSThomas Munro 		break;
2467bb24ee2bSThomas Munro 	case LioMode:
2468bb24ee2bSThomas Munro 		fputs(xlookup(lio_modes, args[sc->offset]), fp);
2469bb24ee2bSThomas Munro 		break;
247098fdbeecSJohn Baldwin 	case Madvice:
247198fdbeecSJohn Baldwin 		print_integer_arg(sysdecode_madvice, fp, args[sc->offset]);
247298fdbeecSJohn Baldwin 		break;
247358227c60SMichael Tuexen 	case Socklent:
247458227c60SMichael Tuexen 		fprintf(fp, "%u", (socklen_t)args[sc->offset]);
247558227c60SMichael Tuexen 		break;
2476ecac235bSMichael Tuexen 	case Sockprotocol: {
2477738a93a4SMichael Tuexen 		const char *temp;
2478738a93a4SMichael Tuexen 		int domain, protocol;
2479ecac235bSMichael Tuexen 
2480738a93a4SMichael Tuexen 		domain = args[sc->offset - 2];
2481ecac235bSMichael Tuexen 		protocol = args[sc->offset];
2482ecac235bSMichael Tuexen 		if (protocol == 0) {
2483ecac235bSMichael Tuexen 			fputs("0", fp);
2484ecac235bSMichael Tuexen 		} else {
2485738a93a4SMichael Tuexen 			temp = sysdecode_socket_protocol(domain, protocol);
2486738a93a4SMichael Tuexen 			if (temp) {
2487738a93a4SMichael Tuexen 				fputs(temp, fp);
2488738a93a4SMichael Tuexen 			} else {
2489738a93a4SMichael Tuexen 				fprintf(fp, "%d", protocol);
2490738a93a4SMichael Tuexen 			}
2491ecac235bSMichael Tuexen 		}
2492ecac235bSMichael Tuexen 		break;
2493ecac235bSMichael Tuexen 	}
2494832af457SMichael Tuexen 	case Sockoptlevel:
2495832af457SMichael Tuexen 		print_integer_arg(sysdecode_sockopt_level, fp,
2496832af457SMichael Tuexen 		    args[sc->offset]);
2497832af457SMichael Tuexen 		break;
2498832af457SMichael Tuexen 	case Sockoptname: {
2499832af457SMichael Tuexen 		const char *temp;
2500832af457SMichael Tuexen 		int level, name;
2501832af457SMichael Tuexen 
2502832af457SMichael Tuexen 		level = args[sc->offset - 1];
2503832af457SMichael Tuexen 		name = args[sc->offset];
2504832af457SMichael Tuexen 		temp = sysdecode_sockopt_name(level, name);
2505832af457SMichael Tuexen 		if (temp) {
2506832af457SMichael Tuexen 			fputs(temp, fp);
2507832af457SMichael Tuexen 		} else {
2508832af457SMichael Tuexen 			fprintf(fp, "%d", name);
2509832af457SMichael Tuexen 		}
2510832af457SMichael Tuexen 		break;
2511832af457SMichael Tuexen 	}
25128b429b65SMichael Tuexen 	case Msgflags:
25138b429b65SMichael Tuexen 		print_mask_arg(sysdecode_msg_flags, fp, args[sc->offset]);
25148b429b65SMichael Tuexen 		break;
25157136a1d9SJohn Baldwin 	case CapRights: {
25167136a1d9SJohn Baldwin 		cap_rights_t rights;
25177136a1d9SJohn Baldwin 
2518cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &rights,
25197136a1d9SJohn Baldwin 		    sizeof(rights)) != -1) {
25207136a1d9SJohn Baldwin 			fputs("{ ", fp);
25217136a1d9SJohn Baldwin 			sysdecode_cap_rights(fp, &rights);
25227136a1d9SJohn Baldwin 			fputs(" }", fp);
25237136a1d9SJohn Baldwin 		} else
2524cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
25257136a1d9SJohn Baldwin 		break;
25267136a1d9SJohn Baldwin 	}
25277ce44f08SJohn Baldwin 	case Acltype:
25287ce44f08SJohn Baldwin 		print_integer_arg(sysdecode_acltype, fp, args[sc->offset]);
25297ce44f08SJohn Baldwin 		break;
253026606dcaSJohn Baldwin 	case Extattrnamespace:
253126606dcaSJohn Baldwin 		print_integer_arg(sysdecode_extattrnamespace, fp,
253226606dcaSJohn Baldwin 		    args[sc->offset]);
253326606dcaSJohn Baldwin 		break;
25342d9c9988SJohn Baldwin 	case Minherit:
25352d9c9988SJohn Baldwin 		print_integer_arg(sysdecode_minherit_inherit, fp,
25362d9c9988SJohn Baldwin 		    args[sc->offset]);
25372d9c9988SJohn Baldwin 		break;
253894bde755SJohn Baldwin 	case Mlockall:
253994bde755SJohn Baldwin 		print_mask_arg(sysdecode_mlockall_flags, fp, args[sc->offset]);
254094bde755SJohn Baldwin 		break;
25418acc8e78SJohn Baldwin 	case Mountflags:
25428acc8e78SJohn Baldwin 		print_mask_arg(sysdecode_mount_flags, fp, args[sc->offset]);
25438acc8e78SJohn Baldwin 		break;
2544114aeee0SJohn Baldwin 	case Msync:
2545114aeee0SJohn Baldwin 		print_mask_arg(sysdecode_msync_flags, fp, args[sc->offset]);
2546114aeee0SJohn Baldwin 		break;
2547ad419d33SJohn Baldwin 	case Priowhich:
2548ad419d33SJohn Baldwin 		print_integer_arg(sysdecode_prio_which, fp, args[sc->offset]);
2549ad419d33SJohn Baldwin 		break;
25505ac1c7acSJohn Baldwin 	case Ptraceop:
25515ac1c7acSJohn Baldwin 		print_integer_arg(sysdecode_ptrace_request, fp,
25525ac1c7acSJohn Baldwin 		    args[sc->offset]);
25535ac1c7acSJohn Baldwin 		break;
255490da2c79SMark Johnston 	case Sendfileflags:
255590da2c79SMark Johnston 		print_mask_arg(sysdecode_sendfile_flags, fp, args[sc->offset]);
255690da2c79SMark Johnston 		break;
255790da2c79SMark Johnston 	case Sendfilehdtr: {
255890da2c79SMark Johnston 		struct sf_hdtr hdtr;
255990da2c79SMark Johnston 
256090da2c79SMark Johnston 		if (get_struct(pid, args[sc->offset], &hdtr, sizeof(hdtr)) !=
256190da2c79SMark Johnston 		    -1) {
256290da2c79SMark Johnston 			fprintf(fp, "{");
256390da2c79SMark Johnston 			print_iovec(fp, trussinfo, (uintptr_t)hdtr.headers,
256490da2c79SMark Johnston 			    hdtr.hdr_cnt);
256590da2c79SMark Johnston 			print_iovec(fp, trussinfo, (uintptr_t)hdtr.trailers,
256690da2c79SMark Johnston 			    hdtr.trl_cnt);
256790da2c79SMark Johnston 			fprintf(fp, "}");
256890da2c79SMark Johnston 		} else
256990da2c79SMark Johnston 			print_pointer(fp, args[sc->offset]);
257090da2c79SMark Johnston 		break;
257190da2c79SMark Johnston 	}
2572dd0c462cSJohn Baldwin 	case Quotactlcmd:
2573dd0c462cSJohn Baldwin 		if (!sysdecode_quotactl_cmd(fp, args[sc->offset]))
2574dd0c462cSJohn Baldwin 			fprintf(fp, "%#x", (int)args[sc->offset]);
2575dd0c462cSJohn Baldwin 		break;
25764152441fSJohn Baldwin 	case Reboothowto:
25774152441fSJohn Baldwin 		print_mask_arg(sysdecode_reboot_howto, fp, args[sc->offset]);
25784152441fSJohn Baldwin 		break;
25793cd40bc3SJohn Baldwin 	case Rtpriofunc:
25803cd40bc3SJohn Baldwin 		print_integer_arg(sysdecode_rtprio_function, fp,
25813cd40bc3SJohn Baldwin 		    args[sc->offset]);
25823cd40bc3SJohn Baldwin 		break;
2583a4110f9fSJohn Baldwin 	case Schedpolicy:
2584a4110f9fSJohn Baldwin 		print_integer_arg(sysdecode_scheduler_policy, fp,
2585a4110f9fSJohn Baldwin 		    args[sc->offset]);
2586a4110f9fSJohn Baldwin 		break;
2587a4110f9fSJohn Baldwin 	case Schedparam: {
2588a4110f9fSJohn Baldwin 		struct sched_param sp;
2589a4110f9fSJohn Baldwin 
2590cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &sp, sizeof(sp)) != -1)
2591a4110f9fSJohn Baldwin 			fprintf(fp, "{ %d }", sp.sched_priority);
2592a4110f9fSJohn Baldwin 		else
2593cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2594a4110f9fSJohn Baldwin 		break;
2595a4110f9fSJohn Baldwin 	}
259613e5e6b6SJohn Baldwin 	case PSig: {
259713e5e6b6SJohn Baldwin 		int sig;
259813e5e6b6SJohn Baldwin 
2599cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &sig, sizeof(sig)) == 0)
260013e5e6b6SJohn Baldwin 			fprintf(fp, "{ %s }", strsig2(sig));
260113e5e6b6SJohn Baldwin 		else
2602cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
260313e5e6b6SJohn Baldwin 		break;
260413e5e6b6SJohn Baldwin 	}
260513e5e6b6SJohn Baldwin 	case Siginfo: {
260613e5e6b6SJohn Baldwin 		siginfo_t si;
260713e5e6b6SJohn Baldwin 
2608cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset], &si, sizeof(si)) != -1) {
260913e5e6b6SJohn Baldwin 			fprintf(fp, "{ signo=%s", strsig2(si.si_signo));
261013e5e6b6SJohn Baldwin 			decode_siginfo(fp, &si);
261113e5e6b6SJohn Baldwin 			fprintf(fp, " }");
261213e5e6b6SJohn Baldwin 		} else
2613cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
261413e5e6b6SJohn Baldwin 		break;
261513e5e6b6SJohn Baldwin 	}
2616a2674e03SMichael Tuexen 	case Iovec:
2617ee6e58b2SMichael Tuexen 		/*
2618ee6e58b2SMichael Tuexen 		 * Print argument as an array of struct iovec, where the next
2619ee6e58b2SMichael Tuexen 		 * syscall argument is the number of elements of the array.
2620ee6e58b2SMichael Tuexen 		 */
2621ee6e58b2SMichael Tuexen 
2622cc86d14aSBrooks Davis 		print_iovec(fp, trussinfo, args[sc->offset],
2623a2674e03SMichael Tuexen 		    (int)args[sc->offset + 1]);
2624ee6e58b2SMichael Tuexen 		break;
2625bb24ee2bSThomas Munro 	case Aiocb: {
2626bb24ee2bSThomas Munro 		struct aiocb cb;
2627bb24ee2bSThomas Munro 
2628bb24ee2bSThomas Munro 		if (get_struct(pid, args[sc->offset], &cb, sizeof(cb)) != -1)
2629bb24ee2bSThomas Munro 			print_aiocb(fp, &cb);
2630bb24ee2bSThomas Munro 		else
2631bb24ee2bSThomas Munro 			print_pointer(fp, args[sc->offset]);
2632bb24ee2bSThomas Munro 		break;
2633bb24ee2bSThomas Munro 	}
2634bb24ee2bSThomas Munro 	case AiocbArray: {
2635bb24ee2bSThomas Munro 		/*
2636bb24ee2bSThomas Munro 		 * Print argment as an array of pointers to struct aiocb, where
2637bb24ee2bSThomas Munro 		 * the next syscall argument is the number of elements.
2638bb24ee2bSThomas Munro 		 */
2639bb24ee2bSThomas Munro 		uintptr_t cbs[16];
2640bb24ee2bSThomas Munro 		unsigned int nent;
2641bb24ee2bSThomas Munro 		bool truncated;
2642bb24ee2bSThomas Munro 
2643bb24ee2bSThomas Munro 		nent = args[sc->offset + 1];
2644bb24ee2bSThomas Munro 		truncated = false;
2645bb24ee2bSThomas Munro 		if (nent > nitems(cbs)) {
2646bb24ee2bSThomas Munro 			nent = nitems(cbs);
2647bb24ee2bSThomas Munro 			truncated = true;
2648bb24ee2bSThomas Munro 		}
2649bb24ee2bSThomas Munro 
2650bb24ee2bSThomas Munro 		if (get_struct(pid, args[sc->offset], cbs, sizeof(uintptr_t) * nent) != -1) {
2651bb24ee2bSThomas Munro 			unsigned int i;
2652bb24ee2bSThomas Munro 			fputs("[", fp);
2653bb24ee2bSThomas Munro 			for (i = 0; i < nent; ++i) {
2654bb24ee2bSThomas Munro 				struct aiocb cb;
2655bb24ee2bSThomas Munro 				if (i > 0)
2656bb24ee2bSThomas Munro 					fputc(',', fp);
2657bb24ee2bSThomas Munro 				if (get_struct(pid, cbs[i], &cb, sizeof(cb)) != -1)
2658bb24ee2bSThomas Munro 					print_aiocb(fp, &cb);
2659bb24ee2bSThomas Munro 				else
2660bb24ee2bSThomas Munro 					print_pointer(fp, cbs[i]);
2661bb24ee2bSThomas Munro 			}
2662bb24ee2bSThomas Munro 			if (truncated)
2663bb24ee2bSThomas Munro 				fputs(",...", fp);
2664bb24ee2bSThomas Munro 			fputs("]", fp);
2665bb24ee2bSThomas Munro 		} else
2666bb24ee2bSThomas Munro 			print_pointer(fp, args[sc->offset]);
2667bb24ee2bSThomas Munro 		break;
2668bb24ee2bSThomas Munro 	}
2669bb24ee2bSThomas Munro 	case AiocbPointer: {
2670bb24ee2bSThomas Munro 		/*
2671bb24ee2bSThomas Munro 		 * aio_waitcomplete(2) assigns a pointer to a pointer to struct
2672bb24ee2bSThomas Munro 		 * aiocb, so we need to handle the extra layer of indirection.
2673bb24ee2bSThomas Munro 		 */
2674bb24ee2bSThomas Munro 		uintptr_t cbp;
2675bb24ee2bSThomas Munro 		struct aiocb cb;
2676bb24ee2bSThomas Munro 
2677bb24ee2bSThomas Munro 		if (get_struct(pid, args[sc->offset], &cbp, sizeof(cbp)) != -1) {
2678bb24ee2bSThomas Munro 			if (get_struct(pid, cbp, &cb, sizeof(cb)) != -1)
2679bb24ee2bSThomas Munro 				print_aiocb(fp, &cb);
2680bb24ee2bSThomas Munro 			else
2681bb24ee2bSThomas Munro 				print_pointer(fp, cbp);
2682bb24ee2bSThomas Munro 		} else
2683bb24ee2bSThomas Munro 			print_pointer(fp, args[sc->offset]);
2684bb24ee2bSThomas Munro 		break;
2685bb24ee2bSThomas Munro 	}
26864d7b9809SMichael Tuexen 	case Sctpsndrcvinfo: {
26874d7b9809SMichael Tuexen 		struct sctp_sndrcvinfo info;
26884d7b9809SMichael Tuexen 
2689cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset],
26904d7b9809SMichael Tuexen 		    &info, sizeof(struct sctp_sndrcvinfo)) == -1) {
2691cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
26924d7b9809SMichael Tuexen 			break;
26934d7b9809SMichael Tuexen 		}
2694a2674e03SMichael Tuexen 		print_sctp_sndrcvinfo(fp, sc->type & OUT, &info);
2695a2674e03SMichael Tuexen 		break;
26964d7b9809SMichael Tuexen 	}
2697a2674e03SMichael Tuexen 	case Msghdr: {
2698a2674e03SMichael Tuexen 		struct msghdr msghdr;
2699a2674e03SMichael Tuexen 
2700cc86d14aSBrooks Davis 		if (get_struct(pid, args[sc->offset],
2701a2674e03SMichael Tuexen 		    &msghdr, sizeof(struct msghdr)) == -1) {
2702cc86d14aSBrooks Davis 			print_pointer(fp, args[sc->offset]);
2703a2674e03SMichael Tuexen 			break;
27044d7b9809SMichael Tuexen 		}
2705a2674e03SMichael Tuexen 		fputs("{", fp);
2706cc86d14aSBrooks Davis 		print_sockaddr(fp, trussinfo, (uintptr_t)msghdr.msg_name, msghdr.msg_namelen);
2707a2674e03SMichael Tuexen 		fprintf(fp, ",%d,", msghdr.msg_namelen);
2708cc86d14aSBrooks Davis 		print_iovec(fp, trussinfo, (uintptr_t)msghdr.msg_iov, msghdr.msg_iovlen);
2709a2674e03SMichael Tuexen 		fprintf(fp, ",%d,", msghdr.msg_iovlen);
2710a2674e03SMichael Tuexen 		print_cmsgs(fp, pid, sc->type & OUT, &msghdr);
2711a2674e03SMichael Tuexen 		fprintf(fp, ",%u,", msghdr.msg_controllen);
2712a2674e03SMichael Tuexen 		print_mask_arg(sysdecode_msg_flags, fp, msghdr.msg_flags);
2713a2674e03SMichael Tuexen 		fputs("}", fp);
27144d7b9809SMichael Tuexen 		break;
27154d7b9809SMichael Tuexen 	}
2716808d9805SEd Schouten 
2717081e5c48SPav Lucistnik 	default:
2718081e5c48SPav Lucistnik 		errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
2719bbeaf6c0SSean Eric Fagan 	}
2720f083f689SJohn Baldwin 	fclose(fp);
2721d8984f48SDag-Erling Smørgrav 	return (tmp);
2722bbeaf6c0SSean Eric Fagan }
2723bbeaf6c0SSean Eric Fagan 
2724bbeaf6c0SSean Eric Fagan /*
272500ddbdf2SJohn Baldwin  * Print (to outfile) the system call and its arguments.
2726bbeaf6c0SSean Eric Fagan  */
2727bbeaf6c0SSean Eric Fagan void
272800ddbdf2SJohn Baldwin print_syscall(struct trussinfo *trussinfo)
2729d8984f48SDag-Erling Smørgrav {
273000ddbdf2SJohn Baldwin 	struct threadinfo *t;
273100ddbdf2SJohn Baldwin 	const char *name;
273200ddbdf2SJohn Baldwin 	char **s_args;
273300ddbdf2SJohn Baldwin 	int i, len, nargs;
27340d0bd00eSMatthew N. Dodd 
273500ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
2736c03bfcc8SMatthew N. Dodd 
27371175b23fSJohn Baldwin 	name = t->cs.sc->name;
273800ddbdf2SJohn Baldwin 	nargs = t->cs.nargs;
273900ddbdf2SJohn Baldwin 	s_args = t->cs.s_args;
27400d0bd00eSMatthew N. Dodd 
2741d70876fdSJohn Baldwin 	len = print_line_prefix(trussinfo);
2742ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, "%s(", name);
2743c03bfcc8SMatthew N. Dodd 
2744bbeaf6c0SSean Eric Fagan 	for (i = 0; i < nargs; i++) {
274500ddbdf2SJohn Baldwin 		if (s_args[i] != NULL)
2746ec0bed25SMatthew N. Dodd 			len += fprintf(trussinfo->outfile, "%s", s_args[i]);
2747bbeaf6c0SSean Eric Fagan 		else
274894355cfdSAndrey Zonov 			len += fprintf(trussinfo->outfile,
274994355cfdSAndrey Zonov 			    "<missing argument>");
275094355cfdSAndrey Zonov 		len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ?
275194355cfdSAndrey Zonov 		    "," : "");
2752bbeaf6c0SSean Eric Fagan 	}
2753ec0bed25SMatthew N. Dodd 	len += fprintf(trussinfo->outfile, ")");
27546cb533feSSean Eric Fagan 	for (i = 0; i < 6 - (len / 8); i++)
2755ec0bed25SMatthew N. Dodd 		fprintf(trussinfo->outfile, "\t");
27566cb533feSSean Eric Fagan }
27576cb533feSSean Eric Fagan 
27586cb533feSSean Eric Fagan void
2759b1ad6a90SBrooks Davis print_syscall_ret(struct trussinfo *trussinfo, int error, syscallarg_t *retval)
27601bcb5f5aSMarcel Moolenaar {
2761ee3b0f6eSDiomidis Spinellis 	struct timespec timediff;
276200ddbdf2SJohn Baldwin 	struct threadinfo *t;
276300ddbdf2SJohn Baldwin 	struct syscall *sc;
2764ee3b0f6eSDiomidis Spinellis 
276500ddbdf2SJohn Baldwin 	t = trussinfo->curthread;
276600ddbdf2SJohn Baldwin 	sc = t->cs.sc;
2767ee3b0f6eSDiomidis Spinellis 	if (trussinfo->flags & COUNTONLY) {
27686040822cSAlan Somers 		timespecsub(&t->after, &t->before, &timediff);
2769d9dcc463SXin LI 		timespecadd(&sc->time, &timediff, &sc->time);
2770ee3b0f6eSDiomidis Spinellis 		sc->ncalls++;
2771caa449b6SJohn Baldwin 		if (error != 0)
2772ee3b0f6eSDiomidis Spinellis 			sc->nerror++;
2773ee3b0f6eSDiomidis Spinellis 		return;
2774ee3b0f6eSDiomidis Spinellis 	}
2775d8984f48SDag-Erling Smørgrav 
277600ddbdf2SJohn Baldwin 	print_syscall(trussinfo);
27770cf21b4fSBrian Somers 	fflush(trussinfo->outfile);
2778b9befd33SJohn Baldwin 
2779b9befd33SJohn Baldwin 	if (retval == NULL) {
2780b9befd33SJohn Baldwin 		/*
2781b9befd33SJohn Baldwin 		 * This system call resulted in the current thread's exit,
2782b9befd33SJohn Baldwin 		 * so there is no return value or error to display.
2783b9befd33SJohn Baldwin 		 */
2784b9befd33SJohn Baldwin 		fprintf(trussinfo->outfile, "\n");
2785b9befd33SJohn Baldwin 		return;
2786b9befd33SJohn Baldwin 	}
2787b9befd33SJohn Baldwin 
2788caa449b6SJohn Baldwin 	if (error == ERESTART)
2789caa449b6SJohn Baldwin 		fprintf(trussinfo->outfile, " ERESTART\n");
2790caa449b6SJohn Baldwin 	else if (error == EJUSTRETURN)
2791caa449b6SJohn Baldwin 		fprintf(trussinfo->outfile, " EJUSTRETURN\n");
2792caa449b6SJohn Baldwin 	else if (error != 0) {
2793caa449b6SJohn Baldwin 		fprintf(trussinfo->outfile, " ERR#%d '%s'\n",
2794caa449b6SJohn Baldwin 		    sysdecode_freebsd_to_abi_errno(t->proc->abi->abi, error),
2795caa449b6SJohn Baldwin 		    strerror(error));
27968ba2e89eSAlex Richardson 	} else if (sc->decode.ret_type == 2 &&
27978ba2e89eSAlex Richardson 	    t->proc->abi->pointer_size == 4) {
27982b75c8adSJohn Baldwin 		off_t off;
27992b75c8adSJohn Baldwin #if _BYTE_ORDER == _LITTLE_ENDIAN
28002b75c8adSJohn Baldwin 		off = (off_t)retval[1] << 32 | retval[0];
28012b75c8adSJohn Baldwin #else
28022b75c8adSJohn Baldwin 		off = (off_t)retval[0] << 32 | retval[1];
28032b75c8adSJohn Baldwin #endif
28042b75c8adSJohn Baldwin 		fprintf(trussinfo->outfile, " = %jd (0x%jx)\n", (intmax_t)off,
28052b75c8adSJohn Baldwin 		    (intmax_t)off);
28068ba2e89eSAlex Richardson 	} else {
2807caa449b6SJohn Baldwin 		fprintf(trussinfo->outfile, " = %jd (0x%jx)\n",
2808caa449b6SJohn Baldwin 		    (intmax_t)retval[0], (intmax_t)retval[0]);
2809bbeaf6c0SSean Eric Fagan 	}
28108ba2e89eSAlex Richardson }
2811ee3b0f6eSDiomidis Spinellis 
2812ee3b0f6eSDiomidis Spinellis void
2813ee3b0f6eSDiomidis Spinellis print_summary(struct trussinfo *trussinfo)
2814ee3b0f6eSDiomidis Spinellis {
2815ee3b0f6eSDiomidis Spinellis 	struct timespec total = {0, 0};
281694355cfdSAndrey Zonov 	struct syscall *sc;
2817ee3b0f6eSDiomidis Spinellis 	int ncall, nerror;
2818ee3b0f6eSDiomidis Spinellis 
2819ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
2820ee3b0f6eSDiomidis Spinellis 	    "syscall", "seconds", "calls", "errors");
2821ee3b0f6eSDiomidis Spinellis 	ncall = nerror = 0;
28226019514bSAlex Richardson 	STAILQ_FOREACH(sc, &seen_syscalls, entries) {
2823ee3b0f6eSDiomidis Spinellis 		if (sc->ncalls) {
282455a8d2bbSJaakko Heinonen 			fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
282555a8d2bbSJaakko Heinonen 			    sc->name, (intmax_t)sc->time.tv_sec,
282655a8d2bbSJaakko Heinonen 			    sc->time.tv_nsec, sc->ncalls, sc->nerror);
2827d9dcc463SXin LI 			timespecadd(&total, &sc->time, &total);
2828ee3b0f6eSDiomidis Spinellis 			ncall += sc->ncalls;
2829ee3b0f6eSDiomidis Spinellis 			nerror += sc->nerror;
2830ee3b0f6eSDiomidis Spinellis 		}
28316019514bSAlex Richardson 	}
2832ee3b0f6eSDiomidis Spinellis 	fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n",
2833ee3b0f6eSDiomidis Spinellis 	    "", "-------------", "-------", "-------");
283455a8d2bbSJaakko Heinonen 	fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
283555a8d2bbSJaakko Heinonen 	    "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror);
2836ee3b0f6eSDiomidis Spinellis }
2837