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