131567Ssef/* 2204977Simp * Copyright 1997 Sean Eric Fagan 331899Ssef * 431899Ssef * Redistribution and use in source and binary forms, with or without 531899Ssef * modification, are permitted provided that the following conditions 631899Ssef * are met: 731899Ssef * 1. Redistributions of source code must retain the above copyright 831899Ssef * notice, this list of conditions and the following disclaimer. 931899Ssef * 2. Redistributions in binary form must reproduce the above copyright 1031899Ssef * notice, this list of conditions and the following disclaimer in the 1131899Ssef * documentation and/or other materials provided with the distribution. 1231899Ssef * 3. All advertising materials mentioning features or use of this software 1331899Ssef * must display the following acknowledgement: 1431899Ssef * This product includes software developed by Sean Eric Fagan 1531899Ssef * 4. Neither the name of the author may be used to endorse or promote 1631899Ssef * products derived from this software without specific prior written 1731899Ssef * permission. 1831899Ssef * 1931899Ssef * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2031899Ssef * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2131899Ssef * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2231899Ssef * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2331899Ssef * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2431899Ssef * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2531899Ssef * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2631899Ssef * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2731899Ssef * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2831899Ssef * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2931899Ssef * SUCH DAMAGE. 3031899Ssef */ 3131899Ssef 32288424Sjhb#include <sys/cdefs.h> 33288424Sjhb__FBSDID("$FreeBSD: releng/11.0/usr.bin/truss/syscalls.c 304477 2016-08-19 17:48:47Z bdrewery $"); 3432275Scharnier 3531899Ssef/* 3631567Ssef * This file has routines used to print out system calls and their 3731567Ssef * arguments. 3831567Ssef */ 3931567Ssef 40255493Sjhb#include <sys/types.h> 41288424Sjhb#include <sys/event.h> 42288424Sjhb#include <sys/ioccom.h> 43127328Salfred#include <sys/mman.h> 44288625Sbdrewery#include <sys/mount.h> 45255708Sjhb#include <sys/procctl.h> 46168569Sdelphij#include <sys/ptrace.h> 47288424Sjhb#include <sys/resource.h> 4885292Sdes#include <sys/socket.h> 49288424Sjhb#include <sys/stat.h> 50288424Sjhb#include <sys/umtx.h> 5185292Sdes#include <sys/un.h> 52255493Sjhb#include <sys/wait.h> 53288424Sjhb#include <machine/sysarch.h> 5485292Sdes#include <netinet/in.h> 5585292Sdes#include <arpa/inet.h> 5685292Sdes 5786138Sgreen#include <ctype.h> 5832275Scharnier#include <err.h> 59127328Salfred#include <fcntl.h> 60127332Sdwmalone#include <poll.h> 6185292Sdes#include <signal.h> 62289004Sed#include <stdbool.h> 63288456Sjhb#include <stddef.h> 64127332Sdwmalone#include <stdint.h> 6531567Ssef#include <stdio.h> 6631567Ssef#include <stdlib.h> 6731567Ssef#include <string.h> 68292236Sjhb#include <sysdecode.h> 69101423Smdodd#include <time.h> 7031567Ssef#include <unistd.h> 71158630Spav#include <vis.h> 7285292Sdes 73297247Sed#include <contrib/cloudabi/cloudabi_types_common.h> 74289004Sed 75101282Smdodd#include "truss.h" 7687703Smarkm#include "extern.h" 7731567Ssef#include "syscall.h" 7831567Ssef 79171646Smarcel/* 64-bit alignment on 32-bit platforms. */ 80288454Sjhb#if !defined(__LP64__) && defined(__powerpc__) 81171646Smarcel#define QUAD_ALIGN 1 82171646Smarcel#else 83171646Smarcel#define QUAD_ALIGN 0 84171646Smarcel#endif 85171646Smarcel 86171646Smarcel/* Number of slots needed for a 64-bit argument. */ 87171646Smarcel#ifdef __LP64__ 88171646Smarcel#define QUAD_SLOTS 1 89171646Smarcel#else 90171646Smarcel#define QUAD_SLOTS 2 91171646Smarcel#endif 92171646Smarcel 9331567Ssef/* 94158630Spav * This should probably be in its own file, sorted alphabetically. 9531567Ssef */ 96288832Sbdrewerystatic struct syscall decoded_syscalls[] = { 97288950Sjhb /* Native ABI */ 98288950Sjhb { .name = "__getcwd", .ret_type = 1, .nargs = 2, 99288950Sjhb .args = { { Name | OUT, 0 }, { Int, 1 } } }, 100288950Sjhb { .name = "_umtx_op", .ret_type = 1, .nargs = 5, 101288950Sjhb .args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 }, 102288950Sjhb { Ptr, 4 } } }, 103288950Sjhb { .name = "accept", .ret_type = 1, .nargs = 3, 104288950Sjhb .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, 105288950Sjhb { .name = "access", .ret_type = 1, .nargs = 2, 106288950Sjhb .args = { { Name | IN, 0 }, { Accessmode, 1 } } }, 107288950Sjhb { .name = "bind", .ret_type = 1, .nargs = 3, 108288950Sjhb .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, 109288950Sjhb { .name = "bindat", .ret_type = 1, .nargs = 4, 110288950Sjhb .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, 111286381Sjhb { Int, 3 } } }, 112288950Sjhb { .name = "break", .ret_type = 1, .nargs = 1, 113288950Sjhb .args = { { Ptr, 0 } } }, 114288424Sjhb { .name = "chdir", .ret_type = 1, .nargs = 1, 115192025Sdds .args = { { Name, 0 } } }, 116288950Sjhb { .name = "chflags", .ret_type = 1, .nargs = 2, 117288950Sjhb .args = { { Name | IN, 0 }, { Hex, 1 } } }, 118288950Sjhb { .name = "chmod", .ret_type = 1, .nargs = 2, 119288950Sjhb .args = { { Name, 0 }, { Octal, 1 } } }, 120288950Sjhb { .name = "chown", .ret_type = 1, .nargs = 3, 121288950Sjhb .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, 122288424Sjhb { .name = "chroot", .ret_type = 1, .nargs = 1, 123192025Sdds .args = { { Name, 0 } } }, 124288950Sjhb { .name = "clock_gettime", .ret_type = 1, .nargs = 2, 125288950Sjhb .args = { { Int, 0 }, { Timespec | OUT, 1 } } }, 126288950Sjhb { .name = "close", .ret_type = 1, .nargs = 1, 127288950Sjhb .args = { { Int, 0 } } }, 128288950Sjhb { .name = "connect", .ret_type = 1, .nargs = 3, 129288950Sjhb .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, 130288950Sjhb { .name = "connectat", .ret_type = 1, .nargs = 4, 131288950Sjhb .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, 132288950Sjhb { Int, 3 } } }, 133288950Sjhb { .name = "eaccess", .ret_type = 1, .nargs = 2, 134288950Sjhb .args = { { Name | IN, 0 }, { Accessmode, 1 } } }, 135288950Sjhb { .name = "execve", .ret_type = 1, .nargs = 3, 136288950Sjhb .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 }, 137288950Sjhb { ExecEnv | IN, 2 } } }, 138288950Sjhb { .name = "exit", .ret_type = 0, .nargs = 1, 139288950Sjhb .args = { { Hex, 0 } } }, 140288950Sjhb { .name = "faccessat", .ret_type = 1, .nargs = 4, 141288950Sjhb .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 }, 142288950Sjhb { Atflags, 3 } } }, 143288424Sjhb { .name = "fchmod", .ret_type = 1, .nargs = 2, 144286381Sjhb .args = { { Int, 0 }, { Octal, 1 } } }, 145288424Sjhb { .name = "fchmodat", .ret_type = 1, .nargs = 4, 146286381Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Atflags, 3 } } }, 147288424Sjhb { .name = "fchown", .ret_type = 1, .nargs = 3, 148286381Sjhb .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } }, 149288424Sjhb { .name = "fchownat", .ret_type = 1, .nargs = 5, 150286381Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 }, 151286381Sjhb { Atflags, 4 } } }, 152288950Sjhb { .name = "fcntl", .ret_type = 1, .nargs = 3, 153288950Sjhb .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } }, 154192025Sdds { .name = "fstat", .ret_type = 1, .nargs = 2, 155286330Sjhb .args = { { Int, 0 }, { Stat | OUT, 1 } } }, 156286381Sjhb { .name = "fstatat", .ret_type = 1, .nargs = 4, 157286381Sjhb .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat | OUT, 2 }, 158286381Sjhb { Atflags, 3 } } }, 159288625Sbdrewery { .name = "fstatfs", .ret_type = 1, .nargs = 2, 160288625Sbdrewery .args = { { Int, 0 }, { StatFs | OUT, 1 } } }, 161288950Sjhb { .name = "ftruncate", .ret_type = 1, .nargs = 2, 162288950Sjhb .args = { { Int | IN, 0 }, { QuadHex | IN, 1 + QUAD_ALIGN } } }, 163288950Sjhb { .name = "futimens", .ret_type = 1, .nargs = 2, 164288950Sjhb .args = { { Int, 0 }, { Timespec2 | IN, 1 } } }, 165288950Sjhb { .name = "futimes", .ret_type = 1, .nargs = 2, 166288950Sjhb .args = { { Int, 0 }, { Timeval2 | IN, 1 } } }, 167288950Sjhb { .name = "futimesat", .ret_type = 1, .nargs = 3, 168288950Sjhb .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timeval2 | IN, 2 } } }, 169288950Sjhb { .name = "getitimer", .ret_type = 1, .nargs = 2, 170288950Sjhb .args = { { Int, 0 }, { Itimerval | OUT, 2 } } }, 171192025Sdds { .name = "getpeername", .ret_type = 1, .nargs = 3, 172192025Sdds .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, 173288950Sjhb { .name = "getpgid", .ret_type = 1, .nargs = 1, 174288950Sjhb .args = { { Int, 0 } } }, 175288950Sjhb { .name = "getrlimit", .ret_type = 1, .nargs = 2, 176288950Sjhb .args = { { Resource, 0 }, { Rlimit | OUT, 1 } } }, 177288950Sjhb { .name = "getrusage", .ret_type = 1, .nargs = 2, 178288950Sjhb .args = { { Int, 0 }, { Rusage | OUT, 1 } } }, 179288950Sjhb { .name = "getsid", .ret_type = 1, .nargs = 1, 180288950Sjhb .args = { { Int, 0 } } }, 181192025Sdds { .name = "getsockname", .ret_type = 1, .nargs = 3, 182192025Sdds .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, 183288950Sjhb { .name = "gettimeofday", .ret_type = 1, .nargs = 2, 184288950Sjhb .args = { { Timeval | OUT, 0 }, { Ptr, 1 } } }, 185288950Sjhb { .name = "ioctl", .ret_type = 1, .nargs = 3, 186288950Sjhb .args = { { Int, 0 }, { Ioctl, 1 }, { Hex, 2 } } }, 187288950Sjhb { .name = "kevent", .ret_type = 1, .nargs = 6, 188288950Sjhb .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, 189288950Sjhb { Int, 4 }, { Timespec, 5 } } }, 190288950Sjhb { .name = "kill", .ret_type = 1, .nargs = 2, 191288950Sjhb .args = { { Int | IN, 0 }, { Signal | IN, 1 } } }, 192288950Sjhb { .name = "kldfind", .ret_type = 1, .nargs = 1, 193192025Sdds .args = { { Name | IN, 0 } } }, 194288950Sjhb { .name = "kldfirstmod", .ret_type = 1, .nargs = 1, 195192025Sdds .args = { { Int, 0 } } }, 196288950Sjhb { .name = "kldload", .ret_type = 1, .nargs = 1, 197192025Sdds .args = { { Name | IN, 0 } } }, 198288424Sjhb { .name = "kldnext", .ret_type = 1, .nargs = 1, 199192025Sdds .args = { { Int, 0 } } }, 200288424Sjhb { .name = "kldstat", .ret_type = 1, .nargs = 2, 201192025Sdds .args = { { Int, 0 }, { Ptr, 1 } } }, 202288950Sjhb { .name = "kldunload", .ret_type = 1, .nargs = 1, 203192025Sdds .args = { { Int, 0 } } }, 204288950Sjhb { .name = "kse_release", .ret_type = 0, .nargs = 1, 205288950Sjhb .args = { { Timespec, 0 } } }, 206288950Sjhb { .name = "lchflags", .ret_type = 1, .nargs = 2, 207288950Sjhb .args = { { Name | IN, 0 }, { Hex, 1 } } }, 208288950Sjhb { .name = "lchmod", .ret_type = 1, .nargs = 2, 209288950Sjhb .args = { { Name, 0 }, { Octal, 1 } } }, 210288950Sjhb { .name = "lchown", .ret_type = 1, .nargs = 3, 211288950Sjhb .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, 212288950Sjhb { .name = "link", .ret_type = 1, .nargs = 2, 213288950Sjhb .args = { { Name, 0 }, { Name, 1 } } }, 214288950Sjhb { .name = "linkat", .ret_type = 1, .nargs = 5, 215288950Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 }, 216288950Sjhb { Atflags, 4 } } }, 217288950Sjhb { .name = "lseek", .ret_type = 2, .nargs = 3, 218288950Sjhb .args = { { Int, 0 }, { QuadHex, 1 + QUAD_ALIGN }, 219288950Sjhb { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, 220288950Sjhb { .name = "lstat", .ret_type = 1, .nargs = 2, 221288950Sjhb .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, 222288950Sjhb { .name = "lutimes", .ret_type = 1, .nargs = 2, 223288950Sjhb .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, 224288950Sjhb { .name = "mkdir", .ret_type = 1, .nargs = 2, 225288950Sjhb .args = { { Name, 0 }, { Octal, 1 } } }, 226288950Sjhb { .name = "mkdirat", .ret_type = 1, .nargs = 3, 227288950Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } }, 228288950Sjhb { .name = "mkfifo", .ret_type = 1, .nargs = 2, 229288950Sjhb .args = { { Name, 0 }, { Octal, 1 } } }, 230288950Sjhb { .name = "mkfifoat", .ret_type = 1, .nargs = 3, 231288950Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } }, 232288950Sjhb { .name = "mknod", .ret_type = 1, .nargs = 3, 233288950Sjhb .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } }, 234288950Sjhb { .name = "mknodat", .ret_type = 1, .nargs = 4, 235288950Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } }, 236288950Sjhb { .name = "mmap", .ret_type = 1, .nargs = 6, 237288950Sjhb .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, 238288950Sjhb { Int, 4 }, { QuadHex, 5 + QUAD_ALIGN } } }, 239288834Sbdrewery { .name = "modfind", .ret_type = 1, .nargs = 1, 240288834Sbdrewery .args = { { Name | IN, 0 } } }, 241288950Sjhb { .name = "mount", .ret_type = 1, .nargs = 4, 242288950Sjhb .args = { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } }, 243288950Sjhb { .name = "mprotect", .ret_type = 1, .nargs = 3, 244288950Sjhb .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } }, 245288950Sjhb { .name = "munmap", .ret_type = 1, .nargs = 2, 246288950Sjhb .args = { { Ptr, 0 }, { Int, 1 } } }, 247288424Sjhb { .name = "nanosleep", .ret_type = 1, .nargs = 1, 248192025Sdds .args = { { Timespec, 0 } } }, 249288950Sjhb { .name = "open", .ret_type = 1, .nargs = 3, 250288950Sjhb .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } }, 251288950Sjhb { .name = "openat", .ret_type = 1, .nargs = 4, 252288950Sjhb .args = { { Atfd, 0 }, { Name | IN, 1 }, { Open, 2 }, 253288950Sjhb { Octal, 3 } } }, 254288950Sjhb { .name = "pathconf", .ret_type = 1, .nargs = 2, 255288950Sjhb .args = { { Name | IN, 0 }, { Pathconf, 1 } } }, 256288950Sjhb { .name = "pipe", .ret_type = 1, .nargs = 1, 257288950Sjhb .args = { { PipeFds | OUT, 0 } } }, 258288950Sjhb { .name = "pipe2", .ret_type = 1, .nargs = 2, 259288950Sjhb .args = { { Ptr, 0 }, { Open, 1 } } }, 260288950Sjhb { .name = "poll", .ret_type = 1, .nargs = 3, 261288950Sjhb .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } }, 262288950Sjhb { .name = "posix_openpt", .ret_type = 1, .nargs = 1, 263288950Sjhb .args = { { Open, 0 } } }, 264288950Sjhb { .name = "procctl", .ret_type = 1, .nargs = 4, 265288950Sjhb .args = { { Idtype, 0 }, { Quad, 1 + QUAD_ALIGN }, 266288950Sjhb { Procctl, 1 + QUAD_ALIGN + QUAD_SLOTS }, 267288950Sjhb { Ptr, 2 + QUAD_ALIGN + QUAD_SLOTS } } }, 268288950Sjhb { .name = "read", .ret_type = 1, .nargs = 3, 269288950Sjhb .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } }, 270288950Sjhb { .name = "readlink", .ret_type = 1, .nargs = 3, 271288950Sjhb .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Int, 2 } } }, 272288950Sjhb { .name = "readlinkat", .ret_type = 1, .nargs = 4, 273288950Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 }, 274288950Sjhb { Int, 3 } } }, 275288950Sjhb { .name = "recvfrom", .ret_type = 1, .nargs = 6, 276288950Sjhb .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 }, { Hex, 3 }, 277288950Sjhb { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } }, 278288950Sjhb { .name = "rename", .ret_type = 1, .nargs = 2, 279288950Sjhb .args = { { Name, 0 }, { Name, 1 } } }, 280288950Sjhb { .name = "renameat", .ret_type = 1, .nargs = 4, 281288950Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 } } }, 282288950Sjhb { .name = "rfork", .ret_type = 1, .nargs = 1, 283288950Sjhb .args = { { Rforkflags, 0 } } }, 284304477Sbdrewery { .name = "rmdir", .ret_type = 1, .nargs = 1, 285304477Sbdrewery .args = { { Name, 0 } } }, 286192025Sdds { .name = "select", .ret_type = 1, .nargs = 5, 287286383Sjhb .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, 288286383Sjhb { Timeval, 4 } } }, 289288950Sjhb { .name = "sendto", .ret_type = 1, .nargs = 6, 290288950Sjhb .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 }, 291288950Sjhb { Sockaddr | IN, 4 }, { Ptr | IN, 5 } } }, 292192025Sdds { .name = "setitimer", .ret_type = 1, .nargs = 3, 293286330Sjhb .args = { { Int, 0 }, { Itimerval, 1 }, { Itimerval | OUT, 2 } } }, 294288950Sjhb { .name = "setrlimit", .ret_type = 1, .nargs = 2, 295288950Sjhb .args = { { Resource, 0 }, { Rlimit | IN, 1 } } }, 296288950Sjhb { .name = "shutdown", .ret_type = 1, .nargs = 2, 297288950Sjhb .args = { { Int, 0 }, { Shutdown, 1 } } }, 298288950Sjhb { .name = "sigaction", .ret_type = 1, .nargs = 3, 299288950Sjhb .args = { { Signal, 0 }, { Sigaction | IN, 1 }, 300288950Sjhb { Sigaction | OUT, 2 } } }, 301288424Sjhb { .name = "sigpending", .ret_type = 1, .nargs = 1, 302286848Sjhb .args = { { Sigset | OUT, 0 } } }, 303288424Sjhb { .name = "sigprocmask", .ret_type = 1, .nargs = 3, 304192025Sdds .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } }, 305288424Sjhb { .name = "sigqueue", .ret_type = 1, .nargs = 3, 306286848Sjhb .args = { { Int, 0 }, { Signal, 1 }, { LongHex, 2 } } }, 307288424Sjhb { .name = "sigreturn", .ret_type = 1, .nargs = 1, 308286848Sjhb .args = { { Ptr, 0 } } }, 309288424Sjhb { .name = "sigsuspend", .ret_type = 1, .nargs = 1, 310286848Sjhb .args = { { Sigset | IN, 0 } } }, 311286848Sjhb { .name = "sigtimedwait", .ret_type = 1, .nargs = 3, 312286848Sjhb .args = { { Sigset | IN, 0 }, { Ptr, 1 }, { Timespec | IN, 2 } } }, 313286848Sjhb { .name = "sigwait", .ret_type = 1, .nargs = 2, 314286848Sjhb .args = { { Sigset | IN, 0 }, { Ptr, 1 } } }, 315286848Sjhb { .name = "sigwaitinfo", .ret_type = 1, .nargs = 2, 316286848Sjhb .args = { { Sigset | IN, 0 }, { Ptr, 1 } } }, 317192025Sdds { .name = "socket", .ret_type = 1, .nargs = 3, 318192025Sdds .args = { { Sockdomain, 0 }, { Socktype, 1 }, { Int, 2 } } }, 319288950Sjhb { .name = "stat", .ret_type = 1, .nargs = 2, 320288950Sjhb .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, 321288950Sjhb { .name = "statfs", .ret_type = 1, .nargs = 2, 322288950Sjhb .args = { { Name | IN, 0 }, { StatFs | OUT, 1 } } }, 323192025Sdds { .name = "symlink", .ret_type = 1, .nargs = 2, 324286330Sjhb .args = { { Name, 0 }, { Name, 1 } } }, 325286381Sjhb { .name = "symlinkat", .ret_type = 1, .nargs = 3, 326286381Sjhb .args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } }, 327288950Sjhb { .name = "sysarch", .ret_type = 1, .nargs = 2, 328288950Sjhb .args = { { Sysarch, 0 }, { Ptr, 1 } } }, 329288950Sjhb { .name = "thr_kill", .ret_type = 1, .nargs = 2, 330288950Sjhb .args = { { Long, 0 }, { Signal, 1 } } }, 331288950Sjhb { .name = "thr_self", .ret_type = 1, .nargs = 1, 332288950Sjhb .args = { { Ptr, 0 } } }, 333288950Sjhb { .name = "truncate", .ret_type = 1, .nargs = 2, 334288950Sjhb .args = { { Name | IN, 0 }, { QuadHex | IN, 1 + QUAD_ALIGN } } }, 335288950Sjhb#if 0 336288950Sjhb /* Does not exist */ 337288950Sjhb { .name = "umount", .ret_type = 1, .nargs = 2, 338288950Sjhb .args = { { Name, 0 }, { Int, 2 } } }, 339288950Sjhb#endif 340288950Sjhb { .name = "unlink", .ret_type = 1, .nargs = 1, 341288950Sjhb .args = { { Name, 0 } } }, 342288950Sjhb { .name = "unlinkat", .ret_type = 1, .nargs = 3, 343288950Sjhb .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } }, 344288950Sjhb { .name = "unmount", .ret_type = 1, .nargs = 2, 345288950Sjhb .args = { { Name, 0 }, { Int, 1 } } }, 346288950Sjhb { .name = "utimensat", .ret_type = 1, .nargs = 4, 347288950Sjhb .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 }, 348288950Sjhb { Atflags, 3 } } }, 349288950Sjhb { .name = "utimes", .ret_type = 1, .nargs = 2, 350288950Sjhb .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, 351288957Sbdrewery { .name = "utrace", .ret_type = 1, .nargs = 1, 352288957Sbdrewery .args = { { Utrace, 0 } } }, 353255493Sjhb { .name = "wait4", .ret_type = 1, .nargs = 4, 354255493Sjhb .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 }, 355255493Sjhb { Rusage | OUT, 3 } } }, 356255493Sjhb { .name = "wait6", .ret_type = 1, .nargs = 6, 357288455Sjhb .args = { { Idtype, 0 }, { Quad, 1 + QUAD_ALIGN }, 358288455Sjhb { ExitStatus | OUT, 1 + QUAD_ALIGN + QUAD_SLOTS }, 359288455Sjhb { Waitoptions, 2 + QUAD_ALIGN + QUAD_SLOTS }, 360288455Sjhb { Rusage | OUT, 3 + QUAD_ALIGN + QUAD_SLOTS }, 361288455Sjhb { Ptr, 4 + QUAD_ALIGN + QUAD_SLOTS } } }, 362288950Sjhb { .name = "write", .ret_type = 1, .nargs = 3, 363288950Sjhb .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 } } }, 364288950Sjhb 365288950Sjhb /* Linux ABI */ 366288950Sjhb { .name = "linux_access", .ret_type = 1, .nargs = 2, 367288950Sjhb .args = { { Name, 0 }, { Accessmode, 1 } } }, 368288950Sjhb { .name = "linux_execve", .ret_type = 1, .nargs = 3, 369288950Sjhb .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 }, 370288950Sjhb { ExecEnv | IN, 2 } } }, 371288950Sjhb { .name = "linux_lseek", .ret_type = 2, .nargs = 3, 372288950Sjhb .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } }, 373288950Sjhb { .name = "linux_mkdir", .ret_type = 1, .nargs = 2, 374288950Sjhb .args = { { Name | IN, 0 }, { Int, 1 } } }, 375288950Sjhb { .name = "linux_newfstat", .ret_type = 1, .nargs = 2, 376288950Sjhb .args = { { Int, 0 }, { Ptr | OUT, 1 } } }, 377288950Sjhb { .name = "linux_newstat", .ret_type = 1, .nargs = 2, 378288950Sjhb .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, 379288950Sjhb { .name = "linux_open", .ret_type = 1, .nargs = 3, 380288950Sjhb .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, 381288950Sjhb { .name = "linux_readlink", .ret_type = 1, .nargs = 3, 382288950Sjhb .args = { { Name, 0 }, { Name | OUT, 1 }, { Int, 2 } } }, 383288950Sjhb { .name = "linux_socketcall", .ret_type = 1, .nargs = 2, 384288950Sjhb .args = { { Int, 0 }, { LinuxSockArgs, 1 } } }, 385288950Sjhb { .name = "linux_stat64", .ret_type = 1, .nargs = 3, 386288950Sjhb .args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 } } }, 387288950Sjhb 388289004Sed /* CloudABI system calls. */ 389289004Sed { .name = "cloudabi_sys_clock_res_get", .ret_type = 1, .nargs = 1, 390289004Sed .args = { { CloudABIClockID, 0 } } }, 391289004Sed { .name = "cloudabi_sys_clock_time_get", .ret_type = 1, .nargs = 2, 392289004Sed .args = { { CloudABIClockID, 0 }, { CloudABITimestamp, 1 } } }, 393289004Sed { .name = "cloudabi_sys_condvar_signal", .ret_type = 1, .nargs = 3, 394289004Sed .args = { { Ptr, 0 }, { CloudABIMFlags, 1 }, { UInt, 2 } } }, 395289004Sed { .name = "cloudabi_sys_fd_close", .ret_type = 1, .nargs = 1, 396289004Sed .args = { { Int, 0 } } }, 397289004Sed { .name = "cloudabi_sys_fd_create1", .ret_type = 1, .nargs = 1, 398289004Sed .args = { { CloudABIFileType, 0 } } }, 399289004Sed { .name = "cloudabi_sys_fd_create2", .ret_type = 1, .nargs = 2, 400289004Sed .args = { { CloudABIFileType, 0 }, { PipeFds | OUT, 0 } } }, 401289004Sed { .name = "cloudabi_sys_fd_datasync", .ret_type = 1, .nargs = 1, 402289004Sed .args = { { Int, 0 } } }, 403289004Sed { .name = "cloudabi_sys_fd_dup", .ret_type = 1, .nargs = 1, 404289004Sed .args = { { Int, 0 } } }, 405289004Sed { .name = "cloudabi_sys_fd_replace", .ret_type = 1, .nargs = 2, 406289004Sed .args = { { Int, 0 }, { Int, 1 } } }, 407289004Sed { .name = "cloudabi_sys_fd_seek", .ret_type = 1, .nargs = 3, 408289004Sed .args = { { Int, 0 }, { Int, 1 }, { CloudABIWhence, 2 } } }, 409289004Sed { .name = "cloudabi_sys_fd_stat_get", .ret_type = 1, .nargs = 2, 410289004Sed .args = { { Int, 0 }, { CloudABIFDStat | OUT, 1 } } }, 411289004Sed { .name = "cloudabi_sys_fd_stat_put", .ret_type = 1, .nargs = 3, 412289004Sed .args = { { Int, 0 }, { CloudABIFDStat | IN, 1 }, 413289004Sed { ClouduABIFDSFlags, 2 } } }, 414289004Sed { .name = "cloudabi_sys_fd_sync", .ret_type = 1, .nargs = 1, 415289004Sed .args = { { Int, 0 } } }, 416289004Sed { .name = "cloudabi_sys_file_advise", .ret_type = 1, .nargs = 4, 417289004Sed .args = { { Int, 0 }, { Int, 1 }, { Int, 2 }, 418289004Sed { CloudABIAdvice, 3 } } }, 419289004Sed { .name = "cloudabi_sys_file_allocate", .ret_type = 1, .nargs = 3, 420289004Sed .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } }, 421289004Sed { .name = "cloudabi_sys_file_create", .ret_type = 1, .nargs = 3, 422289004Sed .args = { { Int, 0 }, { BinString | IN, 1 }, 423289004Sed { CloudABIFileType, 3 } } }, 424289004Sed { .name = "cloudabi_sys_file_link", .ret_type = 1, .nargs = 4, 425289004Sed .args = { { CloudABILookup, 0 }, { BinString | IN, 1 }, 426289004Sed { Int, 3 }, { BinString | IN, 4 } } }, 427289004Sed { .name = "cloudabi_sys_file_open", .ret_type = 1, .nargs = 4, 428289004Sed .args = { { Int, 0 }, { BinString | IN, 1 }, 429289004Sed { CloudABIOFlags, 3 }, { CloudABIFDStat | IN, 4 } } }, 430289004Sed { .name = "cloudabi_sys_file_readdir", .ret_type = 1, .nargs = 4, 431289004Sed .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 }, 432289004Sed { Int, 3 } } }, 433289004Sed { .name = "cloudabi_sys_file_readlink", .ret_type = 1, .nargs = 4, 434289004Sed .args = { { Int, 0 }, { BinString | IN, 1 }, 435289004Sed { BinString | OUT, 3 }, { Int, 4 } } }, 436289004Sed { .name = "cloudabi_sys_file_rename", .ret_type = 1, .nargs = 4, 437289004Sed .args = { { Int, 0 }, { BinString | IN, 1 }, 438289004Sed { Int, 3 }, { BinString | IN, 4 } } }, 439289004Sed { .name = "cloudabi_sys_file_stat_fget", .ret_type = 1, .nargs = 2, 440289004Sed .args = { { Int, 0 }, { CloudABIFileStat | OUT, 1 } } }, 441289004Sed { .name = "cloudabi_sys_file_stat_fput", .ret_type = 1, .nargs = 3, 442289004Sed .args = { { Int, 0 }, { CloudABIFileStat | IN, 1 }, 443289004Sed { CloudABIFSFlags, 2 } } }, 444289004Sed { .name = "cloudabi_sys_file_stat_get", .ret_type = 1, .nargs = 3, 445289004Sed .args = { { CloudABILookup, 0 }, { BinString | IN, 1 }, 446289004Sed { CloudABIFileStat | OUT, 3 } } }, 447289004Sed { .name = "cloudabi_sys_file_stat_put", .ret_type = 1, .nargs = 4, 448289004Sed .args = { { CloudABILookup, 0 }, { BinString | IN, 1 }, 449289004Sed { CloudABIFileStat | IN, 3 }, { CloudABIFSFlags, 4 } } }, 450289004Sed { .name = "cloudabi_sys_file_symlink", .ret_type = 1, .nargs = 3, 451289004Sed .args = { { BinString | IN, 0 }, 452289004Sed { Int, 2 }, { BinString | IN, 3 } } }, 453289004Sed { .name = "cloudabi_sys_file_unlink", .ret_type = 1, .nargs = 3, 454289004Sed .args = { { Int, 0 }, { BinString | IN, 1 }, 455289004Sed { CloudABIULFlags, 3 } } }, 456289004Sed { .name = "cloudabi_sys_lock_unlock", .ret_type = 1, .nargs = 2, 457289004Sed .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } }, 458289004Sed { .name = "cloudabi_sys_mem_advise", .ret_type = 1, .nargs = 3, 459289004Sed .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIAdvice, 2 } } }, 460289004Sed { .name = "cloudabi_sys_mem_lock", .ret_type = 1, .nargs = 2, 461289004Sed .args = { { Ptr, 0 }, { Int, 1 } } }, 462289004Sed { .name = "cloudabi_sys_mem_map", .ret_type = 1, .nargs = 6, 463289004Sed .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 }, 464289004Sed { CloudABIMFlags, 3 }, { Int, 4 }, { Int, 5 } } }, 465289004Sed { .name = "cloudabi_sys_mem_protect", .ret_type = 1, .nargs = 3, 466289004Sed .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMProt, 2 } } }, 467289004Sed { .name = "cloudabi_sys_mem_sync", .ret_type = 1, .nargs = 3, 468289004Sed .args = { { Ptr, 0 }, { Int, 1 }, { CloudABIMSFlags, 2 } } }, 469289004Sed { .name = "cloudabi_sys_mem_unlock", .ret_type = 1, .nargs = 2, 470289004Sed .args = { { Ptr, 0 }, { Int, 1 } } }, 471289004Sed { .name = "cloudabi_sys_mem_unmap", .ret_type = 1, .nargs = 2, 472289004Sed .args = { { Ptr, 0 }, { Int, 1 } } }, 473289004Sed { .name = "cloudabi_sys_proc_exec", .ret_type = 1, .nargs = 5, 474289004Sed .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, 475289004Sed { IntArray, 3 }, { Int, 4 } } }, 476289004Sed { .name = "cloudabi_sys_proc_exit", .ret_type = 1, .nargs = 1, 477289004Sed .args = { { Int, 0 } } }, 478289004Sed { .name = "cloudabi_sys_proc_fork", .ret_type = 1, .nargs = 0 }, 479289004Sed { .name = "cloudabi_sys_proc_raise", .ret_type = 1, .nargs = 1, 480289004Sed .args = { { CloudABISignal, 0 } } }, 481289004Sed { .name = "cloudabi_sys_random_get", .ret_type = 1, .nargs = 2, 482289004Sed .args = { { BinString | OUT, 0 }, { Int, 1 } } }, 483289004Sed { .name = "cloudabi_sys_sock_accept", .ret_type = 1, .nargs = 2, 484289004Sed .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 } } }, 485289004Sed { .name = "cloudabi_sys_sock_bind", .ret_type = 1, .nargs = 3, 486289004Sed .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } }, 487289004Sed { .name = "cloudabi_sys_sock_connect", .ret_type = 1, .nargs = 3, 488289004Sed .args = { { Int, 0 }, { Int, 1 }, { BinString | IN, 2 } } }, 489289004Sed { .name = "cloudabi_sys_sock_listen", .ret_type = 1, .nargs = 2, 490289004Sed .args = { { Int, 0 }, { Int, 1 } } }, 491289004Sed { .name = "cloudabi_sys_sock_shutdown", .ret_type = 1, .nargs = 2, 492289004Sed .args = { { Int, 0 }, { CloudABISDFlags, 1 } } }, 493289004Sed { .name = "cloudabi_sys_sock_stat_get", .ret_type = 1, .nargs = 3, 494289004Sed .args = { { Int, 0 }, { CloudABISockStat | OUT, 1 }, 495289004Sed { CloudABISSFlags, 2 } } }, 496289004Sed { .name = "cloudabi_sys_thread_exit", .ret_type = 1, .nargs = 2, 497289004Sed .args = { { Ptr, 0 }, { CloudABIMFlags, 1 } } }, 498289004Sed { .name = "cloudabi_sys_thread_tcb_set", .ret_type = 1, .nargs = 1, 499289004Sed .args = { { Ptr, 0 } } }, 500289004Sed { .name = "cloudabi_sys_thread_yield", .ret_type = 1, .nargs = 0 }, 501289004Sed 502192025Sdds { .name = 0 }, 50331567Ssef}; 504288832Sbdrewerystatic STAILQ_HEAD(, syscall) syscalls; 50531567Ssef 506158630Spav/* Xlat idea taken from strace */ 507158630Spavstruct xlat { 508158630Spav int val; 509168569Sdelphij const char *str; 510158630Spav}; 511158630Spav 512240005Szont#define X(a) { a, #a }, 513240005Szont#define XEND { 0, NULL } 514158630Spav 515158630Spavstatic struct xlat kevent_filters[] = { 516158630Spav X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE) 517158630Spav X(EVFILT_PROC) X(EVFILT_SIGNAL) X(EVFILT_TIMER) 518286358Sjhb X(EVFILT_PROCDESC) X(EVFILT_FS) X(EVFILT_LIO) X(EVFILT_USER) 519286358Sjhb X(EVFILT_SENDFILE) XEND 520158630Spav}; 521158630Spav 522158630Spavstatic struct xlat kevent_flags[] = { 523158630Spav X(EV_ADD) X(EV_DELETE) X(EV_ENABLE) X(EV_DISABLE) X(EV_ONESHOT) 524286358Sjhb X(EV_CLEAR) X(EV_RECEIPT) X(EV_DISPATCH) X(EV_FORCEONESHOT) 525286358Sjhb X(EV_DROP) X(EV_FLAG1) X(EV_ERROR) X(EV_EOF) XEND 526158630Spav}; 527158630Spav 528286914Sjhbstatic struct xlat kevent_user_ffctrl[] = { 529286914Sjhb X(NOTE_FFNOP) X(NOTE_FFAND) X(NOTE_FFOR) X(NOTE_FFCOPY) 530286914Sjhb XEND 531286914Sjhb}; 532286914Sjhb 533286914Sjhbstatic struct xlat kevent_rdwr_fflags[] = { 534286914Sjhb X(NOTE_LOWAT) X(NOTE_FILE_POLL) XEND 535286914Sjhb}; 536286914Sjhb 537286914Sjhbstatic struct xlat kevent_vnode_fflags[] = { 538286914Sjhb X(NOTE_DELETE) X(NOTE_WRITE) X(NOTE_EXTEND) X(NOTE_ATTRIB) 539286914Sjhb X(NOTE_LINK) X(NOTE_RENAME) X(NOTE_REVOKE) XEND 540286914Sjhb}; 541286914Sjhb 542286914Sjhbstatic struct xlat kevent_proc_fflags[] = { 543286914Sjhb X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_TRACK) X(NOTE_TRACKERR) 544286914Sjhb X(NOTE_CHILD) XEND 545286914Sjhb}; 546286914Sjhb 547286914Sjhbstatic struct xlat kevent_timer_fflags[] = { 548286914Sjhb X(NOTE_SECONDS) X(NOTE_MSECONDS) X(NOTE_USECONDS) X(NOTE_NSECONDS) 549286914Sjhb XEND 550286914Sjhb}; 551286914Sjhb 552228396Sedstatic struct xlat poll_flags[] = { 553158630Spav X(POLLSTANDARD) X(POLLIN) X(POLLPRI) X(POLLOUT) X(POLLERR) 554158630Spav X(POLLHUP) X(POLLNVAL) X(POLLRDNORM) X(POLLRDBAND) 555158630Spav X(POLLWRBAND) X(POLLINIGNEOF) XEND 556158630Spav}; 557158630Spav 558158630Spavstatic struct xlat mmap_flags[] = { 559273250Sjhb X(MAP_SHARED) X(MAP_PRIVATE) X(MAP_FIXED) X(MAP_RESERVED0020) 560273250Sjhb X(MAP_RESERVED0040) X(MAP_RESERVED0080) X(MAP_RESERVED0100) 561158630Spav X(MAP_HASSEMAPHORE) X(MAP_STACK) X(MAP_NOSYNC) X(MAP_ANON) 562286358Sjhb X(MAP_EXCL) X(MAP_NOCORE) X(MAP_PREFAULT_READ) 563255426Sjhb#ifdef MAP_32BIT 564255426Sjhb X(MAP_32BIT) 565255426Sjhb#endif 566255426Sjhb XEND 567158630Spav}; 568158630Spav 569158630Spavstatic struct xlat mprot_flags[] = { 570158630Spav X(PROT_NONE) X(PROT_READ) X(PROT_WRITE) X(PROT_EXEC) XEND 571158630Spav}; 572158630Spav 573158630Spavstatic struct xlat whence_arg[] = { 574286358Sjhb X(SEEK_SET) X(SEEK_CUR) X(SEEK_END) X(SEEK_DATA) X(SEEK_HOLE) XEND 575158630Spav}; 576158630Spav 577158630Spavstatic struct xlat sigaction_flags[] = { 578158630Spav X(SA_ONSTACK) X(SA_RESTART) X(SA_RESETHAND) X(SA_NOCLDSTOP) 579158630Spav X(SA_NODEFER) X(SA_NOCLDWAIT) X(SA_SIGINFO) XEND 580158630Spav}; 581158630Spav 582158630Spavstatic struct xlat fcntl_arg[] = { 583158630Spav X(F_DUPFD) X(F_GETFD) X(F_SETFD) X(F_GETFL) X(F_SETFL) 584286358Sjhb X(F_GETOWN) X(F_SETOWN) X(F_OGETLK) X(F_OSETLK) X(F_OSETLKW) 585286358Sjhb X(F_DUP2FD) X(F_GETLK) X(F_SETLK) X(F_SETLKW) X(F_SETLK_REMOTE) 586286358Sjhb X(F_READAHEAD) X(F_RDAHEAD) X(F_DUPFD_CLOEXEC) X(F_DUP2FD_CLOEXEC) 587286358Sjhb XEND 588158630Spav}; 589158630Spav 590158630Spavstatic struct xlat fcntlfd_arg[] = { 591158630Spav X(FD_CLOEXEC) XEND 592158630Spav}; 593158630Spav 594158630Spavstatic struct xlat fcntlfl_arg[] = { 595158630Spav X(O_APPEND) X(O_ASYNC) X(O_FSYNC) X(O_NONBLOCK) X(O_NOFOLLOW) 596286358Sjhb X(FRDAHEAD) X(O_DIRECT) XEND 597158630Spav}; 598158630Spav 599158630Spavstatic struct xlat sockdomain_arg[] = { 600158630Spav X(PF_UNSPEC) X(PF_LOCAL) X(PF_UNIX) X(PF_INET) X(PF_IMPLINK) 601158630Spav X(PF_PUP) X(PF_CHAOS) X(PF_NETBIOS) X(PF_ISO) X(PF_OSI) 602158630Spav X(PF_ECMA) X(PF_DATAKIT) X(PF_CCITT) X(PF_SNA) X(PF_DECnet) 603158630Spav X(PF_DLI) X(PF_LAT) X(PF_HYLINK) X(PF_APPLETALK) X(PF_ROUTE) 604158630Spav X(PF_LINK) X(PF_XTP) X(PF_COIP) X(PF_CNT) X(PF_SIP) X(PF_IPX) 605158630Spav X(PF_RTIP) X(PF_PIP) X(PF_ISDN) X(PF_KEY) X(PF_INET6) 606158630Spav X(PF_NATM) X(PF_ATM) X(PF_NETGRAPH) X(PF_SLOW) X(PF_SCLUSTER) 607286358Sjhb X(PF_ARP) X(PF_BLUETOOTH) X(PF_IEEE80211) X(PF_INET_SDP) 608286358Sjhb X(PF_INET6_SDP) XEND 609158630Spav}; 610158630Spav 611158630Spavstatic struct xlat socktype_arg[] = { 612158630Spav X(SOCK_STREAM) X(SOCK_DGRAM) X(SOCK_RAW) X(SOCK_RDM) 613158630Spav X(SOCK_SEQPACKET) XEND 614158630Spav}; 615158630Spav 616158630Spavstatic struct xlat open_flags[] = { 617158630Spav X(O_RDONLY) X(O_WRONLY) X(O_RDWR) X(O_ACCMODE) X(O_NONBLOCK) 618158630Spav X(O_APPEND) X(O_SHLOCK) X(O_EXLOCK) X(O_ASYNC) X(O_FSYNC) 619158630Spav X(O_NOFOLLOW) X(O_CREAT) X(O_TRUNC) X(O_EXCL) X(O_NOCTTY) 620286358Sjhb X(O_DIRECT) X(O_DIRECTORY) X(O_EXEC) X(O_TTY_INIT) X(O_CLOEXEC) 621286358Sjhb X(O_VERIFY) XEND 622158630Spav}; 623158630Spav 624158630Spavstatic struct xlat shutdown_arg[] = { 625158630Spav X(SHUT_RD) X(SHUT_WR) X(SHUT_RDWR) XEND 626158630Spav}; 627158630Spav 628158630Spavstatic struct xlat resource_arg[] = { 629158630Spav X(RLIMIT_CPU) X(RLIMIT_FSIZE) X(RLIMIT_DATA) X(RLIMIT_STACK) 630158630Spav X(RLIMIT_CORE) X(RLIMIT_RSS) X(RLIMIT_MEMLOCK) X(RLIMIT_NPROC) 631286358Sjhb X(RLIMIT_NOFILE) X(RLIMIT_SBSIZE) X(RLIMIT_VMEM) X(RLIMIT_NPTS) 632286358Sjhb X(RLIMIT_SWAP) X(RLIMIT_KQUEUES) XEND 633158630Spav}; 634158630Spav 635158630Spavstatic struct xlat pathconf_arg[] = { 636158630Spav X(_PC_LINK_MAX) X(_PC_MAX_CANON) X(_PC_MAX_INPUT) 637158630Spav X(_PC_NAME_MAX) X(_PC_PATH_MAX) X(_PC_PIPE_BUF) 638158630Spav X(_PC_CHOWN_RESTRICTED) X(_PC_NO_TRUNC) X(_PC_VDISABLE) 639158630Spav X(_PC_ASYNC_IO) X(_PC_PRIO_IO) X(_PC_SYNC_IO) 640158630Spav X(_PC_ALLOC_SIZE_MIN) X(_PC_FILESIZEBITS) 641158630Spav X(_PC_REC_INCR_XFER_SIZE) X(_PC_REC_MAX_XFER_SIZE) 642158630Spav X(_PC_REC_MIN_XFER_SIZE) X(_PC_REC_XFER_ALIGN) 643158630Spav X(_PC_SYMLINK_MAX) X(_PC_ACL_EXTENDED) X(_PC_ACL_PATH_MAX) 644158630Spav X(_PC_CAP_PRESENT) X(_PC_INF_PRESENT) X(_PC_MAC_PRESENT) 645286358Sjhb X(_PC_ACL_NFS4) X(_PC_MIN_HOLE_SIZE) XEND 646158630Spav}; 647158630Spav 648253850Smarkjstatic struct xlat rfork_flags[] = { 649286358Sjhb X(RFFDG) X(RFPROC) X(RFMEM) X(RFNOWAIT) X(RFCFDG) X(RFTHREAD) 650286358Sjhb X(RFSIGSHARE) X(RFLINUXTHPN) X(RFTSIGZMB) X(RFPPWAIT) XEND 651253850Smarkj}; 652253850Smarkj 653255493Sjhbstatic struct xlat wait_options[] = { 654255493Sjhb X(WNOHANG) X(WUNTRACED) X(WCONTINUED) X(WNOWAIT) X(WEXITED) 655255493Sjhb X(WTRAPPED) XEND 656255493Sjhb}; 657255493Sjhb 658255493Sjhbstatic struct xlat idtype_arg[] = { 659255493Sjhb X(P_PID) X(P_PPID) X(P_PGID) X(P_SID) X(P_CID) X(P_UID) X(P_GID) 660255493Sjhb X(P_ALL) X(P_LWPID) X(P_TASKID) X(P_PROJID) X(P_POOLID) X(P_JAILID) 661255493Sjhb X(P_CTID) X(P_CPUID) X(P_PSETID) XEND 662255493Sjhb}; 663255493Sjhb 664255708Sjhbstatic struct xlat procctl_arg[] = { 665288405Sjhb X(PROC_SPROTECT) X(PROC_REAP_ACQUIRE) X(PROC_REAP_RELEASE) 666288405Sjhb X(PROC_REAP_STATUS) X(PROC_REAP_GETPIDS) X(PROC_REAP_KILL) 667288405Sjhb X(PROC_TRACE_CTL) X(PROC_TRACE_STATUS) XEND 668255708Sjhb}; 669255708Sjhb 670273053Sjhbstatic struct xlat umtx_ops[] = { 671273053Sjhb X(UMTX_OP_RESERVED0) X(UMTX_OP_RESERVED1) X(UMTX_OP_WAIT) 672273053Sjhb X(UMTX_OP_WAKE) X(UMTX_OP_MUTEX_TRYLOCK) X(UMTX_OP_MUTEX_LOCK) 673273053Sjhb X(UMTX_OP_MUTEX_UNLOCK) X(UMTX_OP_SET_CEILING) X(UMTX_OP_CV_WAIT) 674273053Sjhb X(UMTX_OP_CV_SIGNAL) X(UMTX_OP_CV_BROADCAST) X(UMTX_OP_WAIT_UINT) 675273053Sjhb X(UMTX_OP_RW_RDLOCK) X(UMTX_OP_RW_WRLOCK) X(UMTX_OP_RW_UNLOCK) 676273053Sjhb X(UMTX_OP_WAIT_UINT_PRIVATE) X(UMTX_OP_WAKE_PRIVATE) 677273053Sjhb X(UMTX_OP_MUTEX_WAIT) X(UMTX_OP_MUTEX_WAKE) X(UMTX_OP_SEM_WAIT) 678273053Sjhb X(UMTX_OP_SEM_WAKE) X(UMTX_OP_NWAKE_PRIVATE) X(UMTX_OP_MUTEX_WAKE2) 679273604Sjhb X(UMTX_OP_SEM2_WAIT) X(UMTX_OP_SEM2_WAKE) 680273053Sjhb XEND 681273053Sjhb}; 682273053Sjhb 683286381Sjhbstatic struct xlat at_flags[] = { 684286381Sjhb X(AT_EACCESS) X(AT_SYMLINK_NOFOLLOW) X(AT_SYMLINK_FOLLOW) 685286381Sjhb X(AT_REMOVEDIR) XEND 686286381Sjhb}; 687286381Sjhb 688286381Sjhbstatic struct xlat access_modes[] = { 689286381Sjhb X(R_OK) X(W_OK) X(X_OK) XEND 690286381Sjhb}; 691286381Sjhb 692286848Sjhbstatic struct xlat sysarch_ops[] = { 693286848Sjhb#if defined(__i386__) || defined(__amd64__) 694286848Sjhb X(I386_GET_LDT) X(I386_SET_LDT) X(I386_GET_IOPERM) X(I386_SET_IOPERM) 695286848Sjhb X(I386_VM86) X(I386_GET_FSBASE) X(I386_SET_FSBASE) X(I386_GET_GSBASE) 696286848Sjhb X(I386_SET_GSBASE) X(I386_GET_XFPUSTATE) X(AMD64_GET_FSBASE) 697286848Sjhb X(AMD64_SET_FSBASE) X(AMD64_GET_GSBASE) X(AMD64_SET_GSBASE) 698286848Sjhb X(AMD64_GET_XFPUSTATE) 699286848Sjhb#endif 700286848Sjhb XEND 701286848Sjhb}; 702286857Sjhb 703286857Sjhbstatic struct xlat linux_socketcall_ops[] = { 704286857Sjhb X(LINUX_SOCKET) X(LINUX_BIND) X(LINUX_CONNECT) X(LINUX_LISTEN) 705286857Sjhb X(LINUX_ACCEPT) X(LINUX_GETSOCKNAME) X(LINUX_GETPEERNAME) 706286857Sjhb X(LINUX_SOCKETPAIR) X(LINUX_SEND) X(LINUX_RECV) X(LINUX_SENDTO) 707286857Sjhb X(LINUX_RECVFROM) X(LINUX_SHUTDOWN) X(LINUX_SETSOCKOPT) 708286857Sjhb X(LINUX_GETSOCKOPT) X(LINUX_SENDMSG) X(LINUX_RECVMSG) 709286857Sjhb XEND 710286857Sjhb}; 711286857Sjhb 712286860Sjhbstatic struct xlat sigprocmask_ops[] = { 713286860Sjhb X(SIG_BLOCK) X(SIG_UNBLOCK) X(SIG_SETMASK) 714286860Sjhb XEND 715286860Sjhb}; 716286860Sjhb 717158630Spav#undef X 718289004Sed#define X(a) { CLOUDABI_##a, #a }, 719289004Sed 720289004Sedstatic struct xlat cloudabi_advice[] = { 721289004Sed X(ADVICE_DONTNEED) X(ADVICE_NOREUSE) X(ADVICE_NORMAL) 722289004Sed X(ADVICE_RANDOM) X(ADVICE_SEQUENTIAL) X(ADVICE_WILLNEED) 723289004Sed XEND 724289004Sed}; 725289004Sed 726289004Sedstatic struct xlat cloudabi_clockid[] = { 727289004Sed X(CLOCK_MONOTONIC) X(CLOCK_PROCESS_CPUTIME_ID) 728289004Sed X(CLOCK_REALTIME) X(CLOCK_THREAD_CPUTIME_ID) 729289004Sed XEND 730289004Sed}; 731289004Sed 732289004Sedstatic struct xlat cloudabi_errno[] = { 733289004Sed X(E2BIG) X(EACCES) X(EADDRINUSE) X(EADDRNOTAVAIL) 734289004Sed X(EAFNOSUPPORT) X(EAGAIN) X(EALREADY) X(EBADF) X(EBADMSG) 735289004Sed X(EBUSY) X(ECANCELED) X(ECHILD) X(ECONNABORTED) X(ECONNREFUSED) 736289004Sed X(ECONNRESET) X(EDEADLK) X(EDESTADDRREQ) X(EDOM) X(EDQUOT) 737289004Sed X(EEXIST) X(EFAULT) X(EFBIG) X(EHOSTUNREACH) X(EIDRM) X(EILSEQ) 738289004Sed X(EINPROGRESS) X(EINTR) X(EINVAL) X(EIO) X(EISCONN) X(EISDIR) 739289004Sed X(ELOOP) X(EMFILE) X(EMLINK) X(EMSGSIZE) X(EMULTIHOP) 740289004Sed X(ENAMETOOLONG) X(ENETDOWN) X(ENETRESET) X(ENETUNREACH) 741289004Sed X(ENFILE) X(ENOBUFS) X(ENODEV) X(ENOENT) X(ENOEXEC) X(ENOLCK) 742289004Sed X(ENOLINK) X(ENOMEM) X(ENOMSG) X(ENOPROTOOPT) X(ENOSPC) 743289004Sed X(ENOSYS) X(ENOTCONN) X(ENOTDIR) X(ENOTEMPTY) X(ENOTRECOVERABLE) 744289004Sed X(ENOTSOCK) X(ENOTSUP) X(ENOTTY) X(ENXIO) X(EOVERFLOW) 745289004Sed X(EOWNERDEAD) X(EPERM) X(EPIPE) X(EPROTO) X(EPROTONOSUPPORT) 746289004Sed X(EPROTOTYPE) X(ERANGE) X(EROFS) X(ESPIPE) X(ESRCH) X(ESTALE) 747289004Sed X(ETIMEDOUT) X(ETXTBSY) X(EXDEV) X(ENOTCAPABLE) 748289004Sed XEND 749289004Sed}; 750289004Sed 751289004Sedstatic struct xlat cloudabi_fdflags[] = { 752289004Sed X(FDFLAG_APPEND) X(FDFLAG_DSYNC) X(FDFLAG_NONBLOCK) 753289004Sed X(FDFLAG_RSYNC) X(FDFLAG_SYNC) 754289004Sed XEND 755289004Sed}; 756289004Sed 757289004Sedstatic struct xlat cloudabi_fdsflags[] = { 758289004Sed X(FDSTAT_FLAGS) X(FDSTAT_RIGHTS) 759289004Sed XEND 760289004Sed}; 761289004Sed 762289004Sedstatic struct xlat cloudabi_filetype[] = { 763289004Sed X(FILETYPE_UNKNOWN) X(FILETYPE_BLOCK_DEVICE) 764289004Sed X(FILETYPE_CHARACTER_DEVICE) X(FILETYPE_DIRECTORY) 765289004Sed X(FILETYPE_FIFO) X(FILETYPE_POLL) X(FILETYPE_PROCESS) 766289004Sed X(FILETYPE_REGULAR_FILE) X(FILETYPE_SHARED_MEMORY) 767289004Sed X(FILETYPE_SOCKET_DGRAM) X(FILETYPE_SOCKET_SEQPACKET) 768289004Sed X(FILETYPE_SOCKET_STREAM) X(FILETYPE_SYMBOLIC_LINK) 769289004Sed XEND 770289004Sed}; 771289004Sed 772289004Sedstatic struct xlat cloudabi_fsflags[] = { 773289004Sed X(FILESTAT_ATIM) X(FILESTAT_ATIM_NOW) X(FILESTAT_MTIM) 774289004Sed X(FILESTAT_MTIM_NOW) X(FILESTAT_SIZE) 775289004Sed XEND 776289004Sed}; 777289004Sed 778289004Sedstatic struct xlat cloudabi_mflags[] = { 779289004Sed X(MAP_ANON) X(MAP_FIXED) X(MAP_PRIVATE) X(MAP_SHARED) 780289004Sed XEND 781289004Sed}; 782289004Sed 783289004Sedstatic struct xlat cloudabi_mprot[] = { 784289004Sed X(PROT_EXEC) X(PROT_WRITE) X(PROT_READ) 785289004Sed XEND 786289004Sed}; 787289004Sed 788289004Sedstatic struct xlat cloudabi_msflags[] = { 789289004Sed X(MS_ASYNC) X(MS_INVALIDATE) X(MS_SYNC) 790289004Sed XEND 791289004Sed}; 792289004Sed 793289004Sedstatic struct xlat cloudabi_oflags[] = { 794289004Sed X(O_CREAT) X(O_DIRECTORY) X(O_EXCL) X(O_TRUNC) 795289004Sed XEND 796289004Sed}; 797289004Sed 798289004Sedstatic struct xlat cloudabi_sa_family[] = { 799289004Sed X(AF_UNSPEC) X(AF_INET) X(AF_INET6) X(AF_UNIX) 800289004Sed XEND 801289004Sed}; 802289004Sed 803289004Sedstatic struct xlat cloudabi_sdflags[] = { 804289004Sed X(SHUT_RD) X(SHUT_WR) 805289004Sed XEND 806289004Sed}; 807289004Sed 808289004Sedstatic struct xlat cloudabi_signal[] = { 809289004Sed X(SIGABRT) X(SIGALRM) X(SIGBUS) X(SIGCHLD) X(SIGCONT) X(SIGFPE) 810289004Sed X(SIGHUP) X(SIGILL) X(SIGINT) X(SIGKILL) X(SIGPIPE) X(SIGQUIT) 811289004Sed X(SIGSEGV) X(SIGSTOP) X(SIGSYS) X(SIGTERM) X(SIGTRAP) X(SIGTSTP) 812289004Sed X(SIGTTIN) X(SIGTTOU) X(SIGURG) X(SIGUSR1) X(SIGUSR2) 813289004Sed X(SIGVTALRM) X(SIGXCPU) X(SIGXFSZ) 814289004Sed XEND 815289004Sed}; 816289004Sed 817289004Sedstatic struct xlat cloudabi_ssflags[] = { 818289004Sed X(SOCKSTAT_CLEAR_ERROR) 819289004Sed XEND 820289004Sed}; 821289004Sed 822289004Sedstatic struct xlat cloudabi_ssstate[] = { 823297247Sed X(SOCKSTATE_ACCEPTCONN) 824289004Sed XEND 825289004Sed}; 826289004Sed 827289004Sedstatic struct xlat cloudabi_ulflags[] = { 828289004Sed X(UNLINK_REMOVEDIR) 829289004Sed XEND 830289004Sed}; 831289004Sed 832289004Sedstatic struct xlat cloudabi_whence[] = { 833289004Sed X(WHENCE_CUR) X(WHENCE_END) X(WHENCE_SET) 834289004Sed XEND 835289004Sed}; 836289004Sed 837289004Sed#undef X 838158630Spav#undef XEND 839158630Spav 840181061Sdes/* 841181061Sdes * Searches an xlat array for a value, and returns it if found. Otherwise 842181061Sdes * return a string representation. 843181061Sdes */ 844181061Sdesstatic const char * 845181061Sdeslookup(struct xlat *xlat, int val, int base) 846158630Spav{ 847158630Spav static char tmp[16]; 848181061Sdes 849158630Spav for (; xlat->str != NULL; xlat++) 850158630Spav if (xlat->val == val) 851181061Sdes return (xlat->str); 852158630Spav switch (base) { 853158630Spav case 8: 854158630Spav sprintf(tmp, "0%o", val); 855158630Spav break; 856158630Spav case 16: 857158630Spav sprintf(tmp, "0x%x", val); 858158630Spav break; 859158630Spav case 10: 860158630Spav sprintf(tmp, "%u", val); 861158630Spav break; 862158630Spav default: 863158630Spav errx(1,"Unknown lookup base"); 864158630Spav break; 865158630Spav } 866181061Sdes return (tmp); 867158630Spav} 868158630Spav 869168569Sdelphijstatic const char * 870168569Sdelphijxlookup(struct xlat *xlat, int val) 871158630Spav{ 872181061Sdes 873181061Sdes return (lookup(xlat, val, 16)); 874158630Spav} 875158630Spav 876286938Sjhb/* 877286938Sjhb * Searches an xlat array containing bitfield values. Remaining bits 878286938Sjhb * set after removing the known ones are printed at the end: 879286938Sjhb * IN|0x400. 880286938Sjhb */ 881181061Sdesstatic char * 882181061Sdesxlookup_bits(struct xlat *xlat, int val) 883158630Spav{ 884240005Szont int len, rem; 885158630Spav static char str[512]; 886158630Spav 887240005Szont len = 0; 888240005Szont rem = val; 889181061Sdes for (; xlat->str != NULL; xlat++) { 890181061Sdes if ((xlat->val & rem) == xlat->val) { 891286938Sjhb /* 892286938Sjhb * Don't print the "all-bits-zero" string unless all 893286938Sjhb * bits are really zero. 894286938Sjhb */ 895158630Spav if (xlat->val == 0 && val != 0) 896158630Spav continue; 897158630Spav len += sprintf(str + len, "%s|", xlat->str); 898158630Spav rem &= ~(xlat->val); 899158630Spav } 900158630Spav } 901286938Sjhb 902286938Sjhb /* 903286938Sjhb * If we have leftover bits or didn't match anything, print 904286938Sjhb * the remainder. 905286938Sjhb */ 906158630Spav if (rem || len == 0) 907158630Spav len += sprintf(str + len, "0x%x", rem); 908158630Spav if (len && str[len - 1] == '|') 909158630Spav len--; 910158630Spav str[len] = 0; 911181061Sdes return (str); 912158630Spav} 913158630Spav 914288832Sbdreweryvoid 915288832Sbdreweryinit_syscalls(void) 916288832Sbdrewery{ 917288832Sbdrewery struct syscall *sc; 918288832Sbdrewery 919288832Sbdrewery STAILQ_INIT(&syscalls); 920288832Sbdrewery for (sc = decoded_syscalls; sc->name != NULL; sc++) 921288832Sbdrewery STAILQ_INSERT_HEAD(&syscalls, sc, entries); 922288832Sbdrewery} 92331567Ssef/* 92431567Ssef * If/when the list gets big, it might be desirable to do it 92531567Ssef * as a hash table or binary search. 92631567Ssef */ 92731567Ssefstruct syscall * 928288832Sbdreweryget_syscall(const char *name, int nargs) 929181061Sdes{ 930240005Szont struct syscall *sc; 931288832Sbdrewery int i; 93231567Ssef 933133349Salfred if (name == NULL) 934133349Salfred return (NULL); 935288832Sbdrewery STAILQ_FOREACH(sc, &syscalls, entries) 936240005Szont if (strcmp(name, sc->name) == 0) 937181061Sdes return (sc); 938288832Sbdrewery 939288832Sbdrewery /* It is unknown. Add it into the list. */ 940288832Sbdrewery#if DEBUG 941288832Sbdrewery fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name, 942288832Sbdrewery nargs); 943288832Sbdrewery#endif 944288832Sbdrewery 945288832Sbdrewery sc = calloc(1, sizeof(struct syscall)); 946288832Sbdrewery sc->name = strdup(name); 947288832Sbdrewery sc->ret_type = 1; 948288832Sbdrewery sc->nargs = nargs; 949288832Sbdrewery for (i = 0; i < nargs; i++) { 950288832Sbdrewery sc->args[i].offset = i; 951288832Sbdrewery /* Treat all unknown arguments as LongHex. */ 952288832Sbdrewery sc->args[i].type = LongHex; 95331567Ssef } 954288832Sbdrewery STAILQ_INSERT_HEAD(&syscalls, sc, entries); 955288832Sbdrewery 956288832Sbdrewery return (sc); 95731567Ssef} 95831567Ssef 95931567Ssef/* 96085292Sdes * Copy a fixed amount of bytes from the process. 96185292Sdes */ 96287703Smarkmstatic int 963239501Szontget_struct(pid_t pid, void *offset, void *buf, int len) 964181061Sdes{ 965168569Sdelphij struct ptrace_io_desc iorequest; 966181061Sdes 967168569Sdelphij iorequest.piod_op = PIOD_READ_D; 968168569Sdelphij iorequest.piod_offs = offset; 969168569Sdelphij iorequest.piod_addr = buf; 970168569Sdelphij iorequest.piod_len = len; 971168569Sdelphij if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) 972181061Sdes return (-1); 973181061Sdes return (0); 97485292Sdes} 97585292Sdes 976240005Szont#define MAXSIZE 4096 977286331Sjhb 97885292Sdes/* 97931567Ssef * Copy a string from the process. Note that it is 98031567Ssef * expected to be a C string, but if max is set, it will 98131567Ssef * only get that much. 98231567Ssef */ 983168569Sdelphijstatic char * 984286331Sjhbget_string(pid_t pid, void *addr, int max) 985181061Sdes{ 986240005Szont struct ptrace_io_desc iorequest; 987286331Sjhb char *buf, *nbuf; 988286331Sjhb size_t offset, size, totalsize; 989181061Sdes 990286331Sjhb offset = 0; 991286331Sjhb if (max) 992286331Sjhb size = max + 1; 993286331Sjhb else { 994286331Sjhb /* Read up to the end of the current page. */ 995286331Sjhb size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE); 996286331Sjhb if (size > MAXSIZE) 997286331Sjhb size = MAXSIZE; 998286331Sjhb } 999286331Sjhb totalsize = size; 1000168569Sdelphij buf = malloc(totalsize); 1001168569Sdelphij if (buf == NULL) 1002181061Sdes return (NULL); 1003181061Sdes for (;;) { 1004168569Sdelphij iorequest.piod_op = PIOD_READ_D; 1005286331Sjhb iorequest.piod_offs = (char *)addr + offset; 1006286331Sjhb iorequest.piod_addr = buf + offset; 1007168569Sdelphij iorequest.piod_len = size; 1008168569Sdelphij if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) { 1009168569Sdelphij free(buf); 1010181061Sdes return (NULL); 101131567Ssef } 1012286331Sjhb if (memchr(buf + offset, '\0', size) != NULL) 1013286331Sjhb return (buf); 1014286331Sjhb offset += size; 1015286331Sjhb if (totalsize < MAXSIZE && max == 0) { 1016286331Sjhb size = MAXSIZE - totalsize; 1017286331Sjhb if (size > PAGE_SIZE) 1018286331Sjhb size = PAGE_SIZE; 1019286331Sjhb nbuf = realloc(buf, totalsize + size); 1020286331Sjhb if (nbuf == NULL) { 1021286331Sjhb buf[totalsize - 1] = '\0'; 1022168569Sdelphij return (buf); 1023286331Sjhb } 1024286331Sjhb buf = nbuf; 1025286331Sjhb totalsize += size; 1026181061Sdes } else { 1027216224Sjh buf[totalsize - 1] = '\0'; 1028181061Sdes return (buf); 1029168569Sdelphij } 103031567Ssef } 103131567Ssef} 103231567Ssef 1033255493Sjhbstatic char * 1034255493Sjhbstrsig2(int sig) 1035255493Sjhb{ 1036286913Sjhb static char tmp[sizeof(int) * 3 + 1]; 1037286913Sjhb char *ret; 103831567Ssef 1039286913Sjhb ret = strsig(sig); 1040286913Sjhb if (ret == NULL) { 1041286913Sjhb snprintf(tmp, sizeof(tmp), "%d", sig); 1042286913Sjhb ret = tmp; 1043286913Sjhb } 1044286913Sjhb return (ret); 1045255493Sjhb} 1046255493Sjhb 1047286914Sjhbstatic void 1048286914Sjhbprint_kevent(FILE *fp, struct kevent *ke, int input) 1049286914Sjhb{ 1050286914Sjhb 1051286914Sjhb switch (ke->filter) { 1052286914Sjhb case EVFILT_READ: 1053286914Sjhb case EVFILT_WRITE: 1054286914Sjhb case EVFILT_VNODE: 1055286914Sjhb case EVFILT_PROC: 1056286914Sjhb case EVFILT_TIMER: 1057286914Sjhb case EVFILT_PROCDESC: 1058286914Sjhb fprintf(fp, "%ju", (uintmax_t)ke->ident); 1059286914Sjhb break; 1060286914Sjhb case EVFILT_SIGNAL: 1061286914Sjhb fputs(strsig2(ke->ident), fp); 1062286914Sjhb break; 1063286914Sjhb default: 1064286914Sjhb fprintf(fp, "%p", (void *)ke->ident); 1065286914Sjhb } 1066286914Sjhb fprintf(fp, ",%s,%s,", xlookup(kevent_filters, ke->filter), 1067286914Sjhb xlookup_bits(kevent_flags, ke->flags)); 1068286914Sjhb switch (ke->filter) { 1069286914Sjhb case EVFILT_READ: 1070286914Sjhb case EVFILT_WRITE: 1071286914Sjhb fputs(xlookup_bits(kevent_rdwr_fflags, ke->fflags), fp); 1072286914Sjhb break; 1073286914Sjhb case EVFILT_VNODE: 1074286914Sjhb fputs(xlookup_bits(kevent_vnode_fflags, ke->fflags), fp); 1075286914Sjhb break; 1076286914Sjhb case EVFILT_PROC: 1077286914Sjhb case EVFILT_PROCDESC: 1078286914Sjhb fputs(xlookup_bits(kevent_proc_fflags, ke->fflags), fp); 1079286914Sjhb break; 1080286914Sjhb case EVFILT_TIMER: 1081286914Sjhb fputs(xlookup_bits(kevent_timer_fflags, ke->fflags), fp); 1082286914Sjhb break; 1083286914Sjhb case EVFILT_USER: { 1084286914Sjhb int ctrl, data; 1085286914Sjhb 1086286914Sjhb ctrl = ke->fflags & NOTE_FFCTRLMASK; 1087288406Sjhb data = ke->fflags & NOTE_FFLAGSMASK; 1088286914Sjhb if (input) { 1089286914Sjhb fputs(xlookup(kevent_user_ffctrl, ctrl), fp); 1090286914Sjhb if (ke->fflags & NOTE_TRIGGER) 1091286914Sjhb fputs("|NOTE_TRIGGER", fp); 1092286914Sjhb if (data != 0) 1093286914Sjhb fprintf(fp, "|%#x", data); 1094286914Sjhb } else { 1095286914Sjhb fprintf(fp, "%#x", data); 1096286914Sjhb } 1097286914Sjhb break; 1098286914Sjhb } 1099286914Sjhb default: 1100286914Sjhb fprintf(fp, "%#x", ke->fflags); 1101286914Sjhb } 1102286914Sjhb fprintf(fp, ",%p,%p", (void *)ke->data, (void *)ke->udata); 1103286914Sjhb} 1104286914Sjhb 1105288957Sbdrewerystatic void 1106288957Sbdreweryprint_utrace(FILE *fp, void *utrace_addr, size_t len) 1107288957Sbdrewery{ 1108288957Sbdrewery unsigned char *utrace_buffer; 1109288957Sbdrewery 1110288957Sbdrewery fprintf(fp, "{ "); 1111292236Sjhb if (sysdecode_utrace(fp, utrace_addr, len)) { 1112288957Sbdrewery fprintf(fp, " }"); 1113288957Sbdrewery return; 1114288957Sbdrewery } 1115288957Sbdrewery 1116288957Sbdrewery utrace_buffer = utrace_addr; 1117288957Sbdrewery fprintf(fp, "%zu:", len); 1118288957Sbdrewery while (len--) 1119288957Sbdrewery fprintf(fp, " %02x", *utrace_buffer++); 1120288957Sbdrewery fprintf(fp, " }"); 1121288957Sbdrewery} 1122288957Sbdrewery 112331567Ssef/* 112431567Ssef * Converts a syscall argument into a string. Said string is 1125286938Sjhb * allocated via malloc(), so needs to be free()'d. sc is 112631567Ssef * a pointer to the syscall description (see above); args is 112731567Ssef * an array of all of the system call arguments. 112831567Ssef */ 112931567Ssefchar * 1130288424Sjhbprint_arg(struct syscall_args *sc, unsigned long *args, long *retval, 1131240005Szont struct trussinfo *trussinfo) 1132181061Sdes{ 1133286913Sjhb FILE *fp; 1134240005Szont char *tmp; 1135286913Sjhb size_t tmplen; 1136240005Szont pid_t pid; 1137158630Spav 1138286913Sjhb fp = open_memstream(&tmp, &tmplen); 1139288424Sjhb pid = trussinfo->curthread->proc->pid; 1140181061Sdes switch (sc->type & ARG_MASK) { 1141181061Sdes case Hex: 1142286913Sjhb fprintf(fp, "0x%x", (int)args[sc->offset]); 1143181061Sdes break; 1144181061Sdes case Octal: 1145286913Sjhb fprintf(fp, "0%o", (int)args[sc->offset]); 1146181061Sdes break; 1147181061Sdes case Int: 1148286913Sjhb fprintf(fp, "%d", (int)args[sc->offset]); 1149181061Sdes break; 1150289004Sed case UInt: 1151289004Sed fprintf(fp, "%u", (unsigned int)args[sc->offset]); 1152289004Sed break; 1153273053Sjhb case LongHex: 1154286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1155286848Sjhb break; 1156286848Sjhb case Long: 1157286913Sjhb fprintf(fp, "%ld", args[sc->offset]); 1158286848Sjhb break; 1159181061Sdes case Name: { 1160181061Sdes /* NULL-terminated string. */ 1161181061Sdes char *tmp2; 1162286938Sjhb 1163181061Sdes tmp2 = get_string(pid, (void*)args[sc->offset], 0); 1164286913Sjhb fprintf(fp, "\"%s\"", tmp2); 1165181061Sdes free(tmp2); 1166181061Sdes break; 1167181061Sdes } 1168181061Sdes case BinString: { 1169286938Sjhb /* 1170286938Sjhb * Binary block of data that might have printable characters. 1171286938Sjhb * XXX If type|OUT, assume that the length is the syscall's 1172286938Sjhb * return value. Otherwise, assume that the length of the block 1173286938Sjhb * is in the next syscall argument. 1174286938Sjhb */ 1175181061Sdes int max_string = trussinfo->strsize; 1176286938Sjhb char tmp2[max_string + 1], *tmp3; 1177181061Sdes int len; 1178181061Sdes int truncated = 0; 1179158630Spav 1180181061Sdes if (sc->type & OUT) 1181288424Sjhb len = retval[0]; 1182181061Sdes else 1183181061Sdes len = args[sc->offset + 1]; 1184101289Smdodd 1185286938Sjhb /* 1186286938Sjhb * Don't print more than max_string characters, to avoid word 1187286938Sjhb * wrap. If we have to truncate put some ... after the string. 1188286938Sjhb */ 1189181061Sdes if (len > max_string) { 1190181061Sdes len = max_string; 1191181061Sdes truncated = 1; 1192181061Sdes } 1193240005Szont if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) 1194240005Szont != -1) { 1195181061Sdes tmp3 = malloc(len * 4 + 1); 1196181061Sdes while (len) { 1197240005Szont if (strvisx(tmp3, tmp2, len, 1198240005Szont VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string) 1199181061Sdes break; 1200181061Sdes len--; 1201181061Sdes truncated = 1; 1202298089Spfg } 1203286913Sjhb fprintf(fp, "\"%s\"%s", tmp3, truncated ? 1204240005Szont "..." : ""); 1205181061Sdes free(tmp3); 1206181061Sdes } else { 1207286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1208181061Sdes } 1209181061Sdes break; 1210181061Sdes } 1211286963Sjhb case ExecArgs: 1212286963Sjhb case ExecEnv: 1213181061Sdes case StringArray: { 1214286962Sjhb uintptr_t addr; 1215286962Sjhb union { 1216286962Sjhb char *strarray[0]; 1217286962Sjhb char buf[PAGE_SIZE]; 1218286962Sjhb } u; 1219181061Sdes char *string; 1220286962Sjhb size_t len; 1221288424Sjhb u_int first, i; 1222101289Smdodd 1223286962Sjhb /* 1224286963Sjhb * Only parse argv[] and environment arrays from exec calls 1225286963Sjhb * if requested. 1226286963Sjhb */ 1227286963Sjhb if (((sc->type & ARG_MASK) == ExecArgs && 1228286963Sjhb (trussinfo->flags & EXECVEARGS) == 0) || 1229286963Sjhb ((sc->type & ARG_MASK) == ExecEnv && 1230286963Sjhb (trussinfo->flags & EXECVEENVS) == 0)) { 1231286963Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1232286963Sjhb break; 1233286963Sjhb } 1234288406Sjhb 1235286963Sjhb /* 1236286962Sjhb * Read a page of pointers at a time. Punt if the top-level 1237286962Sjhb * pointer is not aligned. Note that the first read is of 1238286962Sjhb * a partial page. 1239286962Sjhb */ 1240286962Sjhb addr = args[sc->offset]; 1241286962Sjhb if (addr % sizeof(char *) != 0) { 1242286962Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1243286962Sjhb break; 1244286962Sjhb } 1245101289Smdodd 1246286962Sjhb len = PAGE_SIZE - (addr & PAGE_MASK); 1247286962Sjhb if (get_struct(pid, (void *)addr, u.buf, len) == -1) { 1248286962Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1249286962Sjhb break; 1250181061Sdes } 1251181061Sdes 1252286962Sjhb fputc('[', fp); 1253286962Sjhb first = 1; 1254286962Sjhb i = 0; 1255286962Sjhb while (u.strarray[i] != NULL) { 1256286962Sjhb string = get_string(pid, u.strarray[i], 0); 1257286962Sjhb fprintf(fp, "%s \"%s\"", first ? "" : ",", string); 1258181061Sdes free(string); 1259286962Sjhb first = 0; 1260286962Sjhb 1261286962Sjhb i++; 1262286962Sjhb if (i == len / sizeof(char *)) { 1263286962Sjhb addr += len; 1264286962Sjhb len = PAGE_SIZE; 1265286962Sjhb if (get_struct(pid, (void *)addr, u.buf, len) == 1266286962Sjhb -1) { 1267286962Sjhb fprintf(fp, ", <inval>"); 1268286962Sjhb break; 1269286962Sjhb } 1270286962Sjhb i = 0; 1271286962Sjhb } 1272181061Sdes } 1273286962Sjhb fputs(" ]", fp); 1274181061Sdes break; 1275181061Sdes } 1276134799Smarcel#ifdef __LP64__ 1277181061Sdes case Quad: 1278288455Sjhb fprintf(fp, "%ld", args[sc->offset]); 1279288455Sjhb break; 1280288455Sjhb case QuadHex: 1281286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1282181061Sdes break; 1283134799Smarcel#else 1284288455Sjhb case Quad: 1285288455Sjhb case QuadHex: { 1286181061Sdes unsigned long long ll; 1287286938Sjhb 1288288424Sjhb#if _BYTE_ORDER == _LITTLE_ENDIAN 1289288424Sjhb ll = (unsigned long long)args[sc->offset + 1] << 32 | 1290288424Sjhb args[sc->offset]; 1291288424Sjhb#else 1292288424Sjhb ll = (unsigned long long)args[sc->offset] << 32 | 1293288424Sjhb args[sc->offset + 1]; 1294288424Sjhb#endif 1295288455Sjhb if ((sc->type & ARG_MASK) == Quad) 1296288455Sjhb fprintf(fp, "%lld", ll); 1297288455Sjhb else 1298288455Sjhb fprintf(fp, "0x%llx", ll); 1299181061Sdes break; 1300181061Sdes } 1301134799Smarcel#endif 1302181061Sdes case Ptr: 1303286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1304181061Sdes break; 1305181061Sdes case Readlinkres: { 1306181061Sdes char *tmp2; 1307286938Sjhb 1308288424Sjhb if (retval[0] == -1) 1309181061Sdes break; 1310288424Sjhb tmp2 = get_string(pid, (void*)args[sc->offset], retval[0]); 1311286913Sjhb fprintf(fp, "\"%s\"", tmp2); 1312181061Sdes free(tmp2); 1313181061Sdes break; 1314181061Sdes } 1315181061Sdes case Ioctl: { 1316286938Sjhb const char *temp; 1317286938Sjhb unsigned long cmd; 1318286938Sjhb 1319286938Sjhb cmd = args[sc->offset]; 1320292622Sjhb temp = sysdecode_ioctlname(cmd); 1321240005Szont if (temp) 1322286913Sjhb fputs(temp, fp); 1323240005Szont else { 1324286913Sjhb fprintf(fp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", 1325286938Sjhb cmd, cmd & IOC_OUT ? "R" : "", 1326286938Sjhb cmd & IOC_IN ? "W" : "", IOCGROUP(cmd), 1327286938Sjhb isprint(IOCGROUP(cmd)) ? (char)IOCGROUP(cmd) : '?', 1328286938Sjhb cmd & 0xFF, IOCPARM_LEN(cmd)); 1329181061Sdes } 1330181061Sdes break; 1331181061Sdes } 1332181061Sdes case Timespec: { 1333181061Sdes struct timespec ts; 1334286938Sjhb 1335240005Szont if (get_struct(pid, (void *)args[sc->offset], &ts, 1336240005Szont sizeof(ts)) != -1) 1337286939Sjhb fprintf(fp, "{ %jd.%09ld }", (intmax_t)ts.tv_sec, 1338240005Szont ts.tv_nsec); 1339181061Sdes else 1340286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1341181061Sdes break; 1342181061Sdes } 1343286381Sjhb case Timespec2: { 1344286381Sjhb struct timespec ts[2]; 1345286381Sjhb const char *sep; 1346286381Sjhb unsigned int i; 1347286381Sjhb 1348286381Sjhb if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) 1349286381Sjhb != -1) { 1350286388Sjhb fputs("{ ", fp); 1351286381Sjhb sep = ""; 1352286381Sjhb for (i = 0; i < nitems(ts); i++) { 1353286381Sjhb fputs(sep, fp); 1354286381Sjhb sep = ", "; 1355286381Sjhb switch (ts[i].tv_nsec) { 1356286381Sjhb case UTIME_NOW: 1357286381Sjhb fprintf(fp, "UTIME_NOW"); 1358286381Sjhb break; 1359286381Sjhb case UTIME_OMIT: 1360286381Sjhb fprintf(fp, "UTIME_OMIT"); 1361286381Sjhb break; 1362286381Sjhb default: 1363286939Sjhb fprintf(fp, "%jd.%09ld", 1364286939Sjhb (intmax_t)ts[i].tv_sec, 1365286939Sjhb ts[i].tv_nsec); 1366286381Sjhb break; 1367286381Sjhb } 1368286381Sjhb } 1369286388Sjhb fputs(" }", fp); 1370286381Sjhb } else 1371286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1372286381Sjhb break; 1373286381Sjhb } 1374181061Sdes case Timeval: { 1375181061Sdes struct timeval tv; 1376286938Sjhb 1377240005Szont if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) 1378240005Szont != -1) 1379286939Sjhb fprintf(fp, "{ %jd.%06ld }", (intmax_t)tv.tv_sec, 1380240005Szont tv.tv_usec); 1381181061Sdes else 1382286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1383181061Sdes break; 1384181061Sdes } 1385181061Sdes case Timeval2: { 1386181061Sdes struct timeval tv[2]; 1387286938Sjhb 1388240005Szont if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) 1389240005Szont != -1) 1390286939Sjhb fprintf(fp, "{ %jd.%06ld, %jd.%06ld }", 1391286939Sjhb (intmax_t)tv[0].tv_sec, tv[0].tv_usec, 1392286939Sjhb (intmax_t)tv[1].tv_sec, tv[1].tv_usec); 1393181061Sdes else 1394286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1395181061Sdes break; 1396181061Sdes } 1397181061Sdes case Itimerval: { 1398181061Sdes struct itimerval itv; 1399286938Sjhb 1400240005Szont if (get_struct(pid, (void *)args[sc->offset], &itv, 1401240005Szont sizeof(itv)) != -1) 1402286939Sjhb fprintf(fp, "{ %jd.%06ld, %jd.%06ld }", 1403286939Sjhb (intmax_t)itv.it_interval.tv_sec, 1404181061Sdes itv.it_interval.tv_usec, 1405286939Sjhb (intmax_t)itv.it_value.tv_sec, 1406181061Sdes itv.it_value.tv_usec); 1407181061Sdes else 1408286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1409181061Sdes break; 1410181061Sdes } 1411264881Ssmh case LinuxSockArgs: 1412264881Ssmh { 1413264881Ssmh struct linux_socketcall_args largs; 1414286938Sjhb 1415264881Ssmh if (get_struct(pid, (void *)args[sc->offset], (void *)&largs, 1416286857Sjhb sizeof(largs)) != -1) 1417286913Sjhb fprintf(fp, "{ %s, 0x%lx }", 1418286857Sjhb lookup(linux_socketcall_ops, largs.what, 10), 1419286857Sjhb (long unsigned int)largs.args); 1420286857Sjhb else 1421286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1422264881Ssmh break; 1423264881Ssmh } 1424181061Sdes case Pollfd: { 1425181061Sdes /* 1426240005Szont * XXX: A Pollfd argument expects the /next/ syscall argument 1427240005Szont * to be the number of fds in the array. This matches the poll 1428240005Szont * syscall. 1429181061Sdes */ 1430181061Sdes struct pollfd *pfd; 1431286913Sjhb int numfds = args[sc->offset + 1]; 1432286913Sjhb size_t bytes = sizeof(struct pollfd) * numfds; 1433286913Sjhb int i; 1434127332Sdwmalone 1435181061Sdes if ((pfd = malloc(bytes)) == NULL) 1436286913Sjhb err(1, "Cannot malloc %zu bytes for pollfd array", 1437240005Szont bytes); 1438240005Szont if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) 1439240005Szont != -1) { 1440286913Sjhb fputs("{", fp); 1441181061Sdes for (i = 0; i < numfds; i++) { 1442286913Sjhb fprintf(fp, " %d/%s", pfd[i].fd, 1443240005Szont xlookup_bits(poll_flags, pfd[i].events)); 1444181061Sdes } 1445286913Sjhb fputs(" }", fp); 1446181061Sdes } else { 1447286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1448181061Sdes } 1449181061Sdes free(pfd); 1450181061Sdes break; 1451127332Sdwmalone } 1452181061Sdes case Fd_set: { 1453181061Sdes /* 1454240005Szont * XXX: A Fd_set argument expects the /first/ syscall argument 1455240005Szont * to be the number of fds in the array. This matches the 1456240005Szont * select syscall. 1457181061Sdes */ 1458181061Sdes fd_set *fds; 1459181061Sdes int numfds = args[0]; 1460286913Sjhb size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS; 1461286913Sjhb int i; 1462127332Sdwmalone 1463181061Sdes if ((fds = malloc(bytes)) == NULL) 1464286913Sjhb err(1, "Cannot malloc %zu bytes for fd_set array", 1465240005Szont bytes); 1466240005Szont if (get_struct(pid, (void *)args[sc->offset], fds, bytes) 1467240005Szont != -1) { 1468286913Sjhb fputs("{", fp); 1469181061Sdes for (i = 0; i < numfds; i++) { 1470286913Sjhb if (FD_ISSET(i, fds)) 1471286913Sjhb fprintf(fp, " %d", i); 1472181061Sdes } 1473286913Sjhb fputs(" }", fp); 1474240005Szont } else 1475286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1476181061Sdes free(fds); 1477181061Sdes break; 1478127332Sdwmalone } 1479255493Sjhb case Signal: 1480286913Sjhb fputs(strsig2(args[sc->offset]), fp); 1481181061Sdes break; 1482181061Sdes case Sigset: { 1483181061Sdes long sig; 1484181061Sdes sigset_t ss; 1485286913Sjhb int i, first; 1486158630Spav 1487181061Sdes sig = args[sc->offset]; 1488240005Szont if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, 1489240005Szont sizeof(ss)) == -1) { 1490286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1491181061Sdes break; 1492181061Sdes } 1493286913Sjhb fputs("{ ", fp); 1494286913Sjhb first = 1; 1495181061Sdes for (i = 1; i < sys_nsig; i++) { 1496255493Sjhb if (sigismember(&ss, i)) { 1497286913Sjhb fprintf(fp, "%s%s", !first ? "|" : "", 1498286913Sjhb strsig(i)); 1499286913Sjhb first = 0; 1500255493Sjhb } 1501181061Sdes } 1502286913Sjhb if (!first) 1503286913Sjhb fputc(' ', fp); 1504286913Sjhb fputc('}', fp); 1505181061Sdes break; 1506181061Sdes } 1507181061Sdes case Sigprocmask: { 1508286913Sjhb fputs(xlookup(sigprocmask_ops, args[sc->offset]), fp); 1509181061Sdes break; 1510127328Salfred } 1511181061Sdes case Fcntlflag: { 1512286938Sjhb /* XXX: Output depends on the value of the previous argument. */ 1513286938Sjhb switch (args[sc->offset - 1]) { 1514181061Sdes case F_SETFD: 1515286913Sjhb fputs(xlookup_bits(fcntlfd_arg, args[sc->offset]), fp); 1516181061Sdes break; 1517181061Sdes case F_SETFL: 1518286913Sjhb fputs(xlookup_bits(fcntlfl_arg, args[sc->offset]), fp); 1519181061Sdes break; 1520181061Sdes case F_GETFD: 1521181061Sdes case F_GETFL: 1522181061Sdes case F_GETOWN: 1523181061Sdes break; 1524181061Sdes default: 1525286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1526181061Sdes break; 1527181061Sdes } 1528181061Sdes break; 1529181061Sdes } 1530181061Sdes case Open: 1531286913Sjhb fputs(xlookup_bits(open_flags, args[sc->offset]), fp); 1532181061Sdes break; 1533181061Sdes case Fcntl: 1534286913Sjhb fputs(xlookup(fcntl_arg, args[sc->offset]), fp); 1535181061Sdes break; 1536181061Sdes case Mprot: 1537286913Sjhb fputs(xlookup_bits(mprot_flags, args[sc->offset]), fp); 1538181061Sdes break; 1539254430Sjhb case Mmapflags: { 1540254430Sjhb int align, flags; 1541254430Sjhb 1542254430Sjhb /* 1543254430Sjhb * MAP_ALIGNED can't be handled by xlookup_bits(), so 1544254430Sjhb * generate that string manually and prepend it to the 1545254430Sjhb * string from xlookup_bits(). Have to be careful to 1546254430Sjhb * avoid outputting MAP_ALIGNED|0 if MAP_ALIGNED is 1547254430Sjhb * the only flag. 1548254430Sjhb */ 1549254430Sjhb flags = args[sc->offset] & ~MAP_ALIGNMENT_MASK; 1550254430Sjhb align = args[sc->offset] & MAP_ALIGNMENT_MASK; 1551254430Sjhb if (align != 0) { 1552254430Sjhb if (align == MAP_ALIGNED_SUPER) 1553286913Sjhb fputs("MAP_ALIGNED_SUPER", fp); 1554254430Sjhb else 1555286913Sjhb fprintf(fp, "MAP_ALIGNED(%d)", 1556254430Sjhb align >> MAP_ALIGNMENT_SHIFT); 1557286913Sjhb if (flags == 0) 1558254430Sjhb break; 1559286913Sjhb fputc('|', fp); 1560254430Sjhb } 1561286913Sjhb fputs(xlookup_bits(mmap_flags, flags), fp); 1562181061Sdes break; 1563254430Sjhb } 1564181061Sdes case Whence: 1565286913Sjhb fputs(xlookup(whence_arg, args[sc->offset]), fp); 1566181061Sdes break; 1567181061Sdes case Sockdomain: 1568286913Sjhb fputs(xlookup(sockdomain_arg, args[sc->offset]), fp); 1569181061Sdes break; 1570286849Sjhb case Socktype: { 1571286849Sjhb int type, flags; 1572286849Sjhb 1573286849Sjhb flags = args[sc->offset] & (SOCK_CLOEXEC | SOCK_NONBLOCK); 1574286849Sjhb type = args[sc->offset] & ~flags; 1575286849Sjhb fputs(xlookup(socktype_arg, type), fp); 1576286849Sjhb if (flags & SOCK_CLOEXEC) 1577286849Sjhb fprintf(fp, "|SOCK_CLOEXEC"); 1578286849Sjhb if (flags & SOCK_NONBLOCK) 1579286849Sjhb fprintf(fp, "|SOCK_NONBLOCK"); 1580181061Sdes break; 1581286849Sjhb } 1582181061Sdes case Shutdown: 1583286913Sjhb fputs(xlookup(shutdown_arg, args[sc->offset]), fp); 1584181061Sdes break; 1585181061Sdes case Resource: 1586286913Sjhb fputs(xlookup(resource_arg, args[sc->offset]), fp); 1587181061Sdes break; 1588181061Sdes case Pathconf: 1589286913Sjhb fputs(xlookup(pathconf_arg, args[sc->offset]), fp); 1590181061Sdes break; 1591253850Smarkj case Rforkflags: 1592286913Sjhb fputs(xlookup_bits(rfork_flags, args[sc->offset]), fp); 1593253850Smarkj break; 1594181061Sdes case Sockaddr: { 1595181061Sdes char addr[64]; 1596181061Sdes struct sockaddr_in *lsin; 1597181061Sdes struct sockaddr_in6 *lsin6; 1598181061Sdes struct sockaddr_un *sun; 1599181061Sdes struct sockaddr *sa; 1600288456Sjhb socklen_t len; 1601181061Sdes u_char *q; 160285292Sdes 1603181061Sdes if (args[sc->offset] == 0) { 1604286913Sjhb fputs("NULL", fp); 1605181061Sdes break; 1606181061Sdes } 1607121606Smarcel 1608181061Sdes /* 1609288456Sjhb * Extract the address length from the next argument. If 1610288456Sjhb * this is an output sockaddr (OUT is set), then the 1611288456Sjhb * next argument is a pointer to a socklen_t. Otherwise 1612288456Sjhb * the next argument contains a socklen_t by value. 1613181061Sdes */ 1614288456Sjhb if (sc->type & OUT) { 1615288456Sjhb if (get_struct(pid, (void *)args[sc->offset + 1], 1616288456Sjhb &len, sizeof(len)) == -1) { 1617288456Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1618181061Sdes break; 1619181061Sdes } 1620288456Sjhb } else 1621288456Sjhb len = args[sc->offset + 1]; 1622288456Sjhb 1623288456Sjhb /* If the length is too small, just bail. */ 1624288456Sjhb if (len < sizeof(*sa)) { 1625288456Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1626288456Sjhb break; 1627181061Sdes } 1628288456Sjhb 1629288456Sjhb sa = calloc(1, len); 1630288456Sjhb if (get_struct(pid, (void *)args[sc->offset], sa, len) == -1) { 1631288456Sjhb free(sa); 1632286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1633286913Sjhb break; 1634181061Sdes } 163585292Sdes 1636288456Sjhb switch (sa->sa_family) { 1637181061Sdes case AF_INET: 1638288456Sjhb if (len < sizeof(*lsin)) 1639288456Sjhb goto sockaddr_short; 1640288456Sjhb lsin = (struct sockaddr_in *)(void *)sa; 1641286938Sjhb inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr)); 1642286913Sjhb fprintf(fp, "{ AF_INET %s:%d }", addr, 1643240005Szont htons(lsin->sin_port)); 1644181061Sdes break; 1645181061Sdes case AF_INET6: 1646288456Sjhb if (len < sizeof(*lsin6)) 1647288456Sjhb goto sockaddr_short; 1648288456Sjhb lsin6 = (struct sockaddr_in6 *)(void *)sa; 1649240005Szont inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, 1650286938Sjhb sizeof(addr)); 1651286913Sjhb fprintf(fp, "{ AF_INET6 [%s]:%d }", addr, 1652240005Szont htons(lsin6->sin6_port)); 1653181061Sdes break; 1654181061Sdes case AF_UNIX: 1655288456Sjhb sun = (struct sockaddr_un *)sa; 1656288456Sjhb fprintf(fp, "{ AF_UNIX \"%.*s\" }", 1657288456Sjhb (int)(len - offsetof(struct sockaddr_un, sun_path)), 1658288456Sjhb sun->sun_path); 1659181061Sdes break; 1660181061Sdes default: 1661288456Sjhb sockaddr_short: 1662286913Sjhb fprintf(fp, 1663286913Sjhb "{ sa_len = %d, sa_family = %d, sa_data = {", 1664286913Sjhb (int)sa->sa_len, (int)sa->sa_family); 1665286913Sjhb for (q = (u_char *)sa->sa_data; 1666288456Sjhb q < (u_char *)sa + len; q++) 1667286913Sjhb fprintf(fp, "%s 0x%02x", 1668286913Sjhb q == (u_char *)sa->sa_data ? "" : ",", 1669286913Sjhb *q); 1670286913Sjhb fputs(" } }", fp); 1671181061Sdes } 1672288456Sjhb free(sa); 1673181061Sdes break; 167486138Sgreen } 1675181061Sdes case Sigaction: { 1676181061Sdes struct sigaction sa; 1677127332Sdwmalone 1678240005Szont if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) 1679240005Szont != -1) { 1680286913Sjhb fputs("{ ", fp); 1681181061Sdes if (sa.sa_handler == SIG_DFL) 1682286913Sjhb fputs("SIG_DFL", fp); 1683181061Sdes else if (sa.sa_handler == SIG_IGN) 1684286913Sjhb fputs("SIG_IGN", fp); 1685181061Sdes else 1686286913Sjhb fprintf(fp, "%p", sa.sa_handler); 1687286913Sjhb fprintf(fp, " %s ss_t }", 1688181061Sdes xlookup_bits(sigaction_flags, sa.sa_flags)); 1689240005Szont } else 1690286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1691181061Sdes break; 1692181061Sdes } 1693181061Sdes case Kevent: { 1694181061Sdes /* 1695286938Sjhb * XXX XXX: The size of the array is determined by either the 1696286938Sjhb * next syscall argument, or by the syscall return value, 1697181061Sdes * depending on which argument number we are. This matches the 1698181061Sdes * kevent syscall, but luckily that's the only syscall that uses 1699181061Sdes * them. 1700181061Sdes */ 1701181061Sdes struct kevent *ke; 1702181061Sdes int numevents = -1; 1703286913Sjhb size_t bytes; 1704286913Sjhb int i; 1705158630Spav 1706181061Sdes if (sc->offset == 1) 1707181061Sdes numevents = args[sc->offset+1]; 1708288424Sjhb else if (sc->offset == 3 && retval[0] != -1) 1709288424Sjhb numevents = retval[0]; 1710158630Spav 1711286913Sjhb if (numevents >= 0) { 1712181061Sdes bytes = sizeof(struct kevent) * numevents; 1713286913Sjhb if ((ke = malloc(bytes)) == NULL) 1714286913Sjhb err(1, 1715286913Sjhb "Cannot malloc %zu bytes for kevent array", 1716286913Sjhb bytes); 1717286913Sjhb } else 1718286913Sjhb ke = NULL; 1719240005Szont if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], 1720240005Szont ke, bytes) != -1) { 1721286913Sjhb fputc('{', fp); 1722286914Sjhb for (i = 0; i < numevents; i++) { 1723286914Sjhb fputc(' ', fp); 1724286914Sjhb print_kevent(fp, &ke[i], sc->offset == 1); 1725286914Sjhb } 1726286913Sjhb fputs(" }", fp); 1727181061Sdes } else { 1728286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1729181061Sdes } 1730181061Sdes free(ke); 1731181061Sdes break; 1732158630Spav } 1733181061Sdes case Stat: { 1734181061Sdes struct stat st; 1735286938Sjhb 1736240005Szont if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) 1737240005Szont != -1) { 1738181061Sdes char mode[12]; 1739286938Sjhb 1740181061Sdes strmode(st.st_mode, mode); 1741286913Sjhb fprintf(fp, 1742286940Sjhb "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode, 1743286940Sjhb (uintmax_t)st.st_ino, (intmax_t)st.st_size, 1744240005Szont (long)st.st_blksize); 1745181061Sdes } else { 1746286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1747181061Sdes } 1748181061Sdes break; 1749181061Sdes } 1750288625Sbdrewery case StatFs: { 1751288625Sbdrewery unsigned int i; 1752288625Sbdrewery struct statfs buf; 1753288626Sbdrewery 1754288625Sbdrewery if (get_struct(pid, (void *)args[sc->offset], &buf, 1755288625Sbdrewery sizeof(buf)) != -1) { 1756288625Sbdrewery char fsid[17]; 1757288625Sbdrewery 1758288625Sbdrewery bzero(fsid, sizeof(fsid)); 1759288625Sbdrewery if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) { 1760288625Sbdrewery for (i = 0; i < sizeof(buf.f_fsid); i++) 1761288625Sbdrewery snprintf(&fsid[i*2], 1762288625Sbdrewery sizeof(fsid) - (i*2), "%02x", 1763288625Sbdrewery ((u_char *)&buf.f_fsid)[i]); 1764288625Sbdrewery } 1765288625Sbdrewery fprintf(fp, 1766288625Sbdrewery "{ fstypename=%s,mntonname=%s,mntfromname=%s," 1767288625Sbdrewery "fsid=%s }", buf.f_fstypename, buf.f_mntonname, 1768288625Sbdrewery buf.f_mntfromname, fsid); 1769288625Sbdrewery } else 1770288625Sbdrewery fprintf(fp, "0x%lx", args[sc->offset]); 1771288625Sbdrewery break; 1772288625Sbdrewery } 1773288625Sbdrewery 1774181061Sdes case Rusage: { 1775181061Sdes struct rusage ru; 1776286938Sjhb 1777240005Szont if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) 1778240005Szont != -1) { 1779286913Sjhb fprintf(fp, 1780286939Sjhb "{ u=%jd.%06ld,s=%jd.%06ld,in=%ld,out=%ld }", 1781286939Sjhb (intmax_t)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec, 1782286939Sjhb (intmax_t)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec, 1783181061Sdes ru.ru_inblock, ru.ru_oublock); 1784240005Szont } else 1785286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1786181061Sdes break; 1787181061Sdes } 1788181061Sdes case Rlimit: { 1789181061Sdes struct rlimit rl; 1790286938Sjhb 1791240005Szont if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) 1792240005Szont != -1) { 1793286913Sjhb fprintf(fp, "{ cur=%ju,max=%ju }", 1794181061Sdes rl.rlim_cur, rl.rlim_max); 1795240005Szont } else 1796286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1797181061Sdes break; 1798181061Sdes } 1799255493Sjhb case ExitStatus: { 1800255493Sjhb int status; 1801286913Sjhb 1802255493Sjhb if (get_struct(pid, (void *)args[sc->offset], &status, 1803255493Sjhb sizeof(status)) != -1) { 1804286913Sjhb fputs("{ ", fp); 1805255493Sjhb if (WIFCONTINUED(status)) 1806286913Sjhb fputs("CONTINUED", fp); 1807255493Sjhb else if (WIFEXITED(status)) 1808286913Sjhb fprintf(fp, "EXITED,val=%d", 1809255493Sjhb WEXITSTATUS(status)); 1810255493Sjhb else if (WIFSIGNALED(status)) 1811286913Sjhb fprintf(fp, "SIGNALED,sig=%s%s", 1812286913Sjhb strsig2(WTERMSIG(status)), 1813255493Sjhb WCOREDUMP(status) ? ",cored" : ""); 1814255493Sjhb else 1815286913Sjhb fprintf(fp, "STOPPED,sig=%s", 1816286913Sjhb strsig2(WTERMSIG(status))); 1817286913Sjhb fputs(" }", fp); 1818255493Sjhb } else 1819286913Sjhb fprintf(fp, "0x%lx", args[sc->offset]); 1820255493Sjhb break; 1821255493Sjhb } 1822255493Sjhb case Waitoptions: 1823286913Sjhb fputs(xlookup_bits(wait_options, args[sc->offset]), fp); 1824255493Sjhb break; 1825255493Sjhb case Idtype: 1826286913Sjhb fputs(xlookup(idtype_arg, args[sc->offset]), fp); 1827255493Sjhb break; 1828255708Sjhb case Procctl: 1829286913Sjhb fputs(xlookup(procctl_arg, args[sc->offset]), fp); 1830255708Sjhb break; 1831273053Sjhb case Umtxop: 1832286913Sjhb fputs(xlookup(umtx_ops, args[sc->offset]), fp); 1833273053Sjhb break; 1834286381Sjhb case Atfd: 1835286381Sjhb if ((int)args[sc->offset] == AT_FDCWD) 1836286913Sjhb fputs("AT_FDCWD", fp); 1837286381Sjhb else 1838286913Sjhb fprintf(fp, "%d", (int)args[sc->offset]); 1839286381Sjhb break; 1840286381Sjhb case Atflags: 1841286913Sjhb fputs(xlookup_bits(at_flags, args[sc->offset]), fp); 1842286381Sjhb break; 1843286381Sjhb case Accessmode: 1844286381Sjhb if (args[sc->offset] == F_OK) 1845286913Sjhb fputs("F_OK", fp); 1846286381Sjhb else 1847286913Sjhb fputs(xlookup_bits(access_modes, args[sc->offset]), fp); 1848286381Sjhb break; 1849286848Sjhb case Sysarch: 1850286913Sjhb fputs(xlookup(sysarch_ops, args[sc->offset]), fp); 1851286848Sjhb break; 1852288424Sjhb case PipeFds: 1853288424Sjhb /* 1854288424Sjhb * The pipe() system call in the kernel returns its 1855288424Sjhb * two file descriptors via return values. However, 1856288424Sjhb * the interface exposed by libc is that pipe() 1857288424Sjhb * accepts a pointer to an array of descriptors. 1858288424Sjhb * Format the output to match the libc API by printing 1859288424Sjhb * the returned file descriptors as a fake argument. 1860288424Sjhb * 1861288424Sjhb * Overwrite the first retval to signal a successful 1862288424Sjhb * return as well. 1863288424Sjhb */ 1864288424Sjhb fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]); 1865288424Sjhb retval[0] = 0; 1866288424Sjhb break; 1867288957Sbdrewery case Utrace: { 1868288957Sbdrewery size_t len; 1869288957Sbdrewery void *utrace_addr; 1870288957Sbdrewery 1871288957Sbdrewery len = args[sc->offset + 1]; 1872288957Sbdrewery utrace_addr = calloc(1, len); 1873288957Sbdrewery if (get_struct(pid, (void *)args[sc->offset], 1874288957Sbdrewery (void *)utrace_addr, len) != -1) 1875288957Sbdrewery print_utrace(fp, utrace_addr, len); 1876288957Sbdrewery else 1877288957Sbdrewery fprintf(fp, "0x%lx", args[sc->offset]); 1878288957Sbdrewery free(utrace_addr); 1879288957Sbdrewery break; 1880288957Sbdrewery } 1881289004Sed case IntArray: { 1882289004Sed int descriptors[16]; 1883289004Sed unsigned long i, ndescriptors; 1884289004Sed bool truncated; 1885289004Sed 1886289004Sed ndescriptors = args[sc->offset + 1]; 1887289004Sed truncated = false; 1888289004Sed if (ndescriptors > nitems(descriptors)) { 1889289004Sed ndescriptors = nitems(descriptors); 1890289004Sed truncated = true; 1891289004Sed } 1892289004Sed if (get_struct(pid, (void *)args[sc->offset], 1893289004Sed descriptors, ndescriptors * sizeof(descriptors[0])) != -1) { 1894289004Sed fprintf(fp, "{"); 1895289004Sed for (i = 0; i < ndescriptors; i++) 1896289004Sed fprintf(fp, i == 0 ? " %d" : ", %d", 1897289004Sed descriptors[i]); 1898289004Sed fprintf(fp, truncated ? ", ... }" : " }"); 1899289004Sed } else 1900289004Sed fprintf(fp, "0x%lx", args[sc->offset]); 1901289004Sed break; 1902289004Sed } 1903289004Sed 1904289004Sed case CloudABIAdvice: 1905289004Sed fputs(xlookup(cloudabi_advice, args[sc->offset]), fp); 1906289004Sed break; 1907289004Sed case CloudABIClockID: 1908289004Sed fputs(xlookup(cloudabi_clockid, args[sc->offset]), fp); 1909289004Sed break; 1910289004Sed case ClouduABIFDSFlags: 1911289004Sed fputs(xlookup_bits(cloudabi_fdsflags, args[sc->offset]), fp); 1912289004Sed break; 1913289004Sed case CloudABIFDStat: { 1914289004Sed cloudabi_fdstat_t fds; 1915289004Sed if (get_struct(pid, (void *)args[sc->offset], &fds, sizeof(fds)) 1916289004Sed != -1) { 1917289004Sed fprintf(fp, "{ %s, ", 1918289004Sed xlookup(cloudabi_filetype, fds.fs_filetype)); 1919289004Sed fprintf(fp, "%s, ... }", 1920289004Sed xlookup_bits(cloudabi_fdflags, fds.fs_flags)); 1921289004Sed } else 1922289004Sed fprintf(fp, "0x%lx", args[sc->offset]); 1923289004Sed break; 1924289004Sed } 1925289004Sed case CloudABIFileStat: { 1926289004Sed cloudabi_filestat_t fsb; 1927289004Sed if (get_struct(pid, (void *)args[sc->offset], &fsb, sizeof(fsb)) 1928289004Sed != -1) 1929289004Sed fprintf(fp, "{ %s, %lu }", 1930289004Sed xlookup(cloudabi_filetype, fsb.st_filetype), 1931289004Sed fsb.st_size); 1932289004Sed else 1933289004Sed fprintf(fp, "0x%lx", args[sc->offset]); 1934289004Sed break; 1935289004Sed } 1936289004Sed case CloudABIFileType: 1937289004Sed fputs(xlookup(cloudabi_filetype, args[sc->offset]), fp); 1938289004Sed break; 1939289004Sed case CloudABIFSFlags: 1940289004Sed fputs(xlookup_bits(cloudabi_fsflags, args[sc->offset]), fp); 1941289004Sed break; 1942289004Sed case CloudABILookup: 1943289004Sed if ((args[sc->offset] & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) != 0) 1944289004Sed fprintf(fp, "%d|LOOKUP_SYMLINK_FOLLOW", 1945289004Sed (int)args[sc->offset]); 1946289004Sed else 1947289004Sed fprintf(fp, "%d", (int)args[sc->offset]); 1948289004Sed break; 1949289004Sed case CloudABIMFlags: 1950289004Sed fputs(xlookup_bits(cloudabi_mflags, args[sc->offset]), fp); 1951289004Sed break; 1952289004Sed case CloudABIMProt: 1953289004Sed fputs(xlookup_bits(cloudabi_mprot, args[sc->offset]), fp); 1954289004Sed break; 1955289004Sed case CloudABIMSFlags: 1956289004Sed fputs(xlookup_bits(cloudabi_msflags, args[sc->offset]), fp); 1957289004Sed break; 1958289004Sed case CloudABIOFlags: 1959289004Sed fputs(xlookup_bits(cloudabi_oflags, args[sc->offset]), fp); 1960289004Sed break; 1961289004Sed case CloudABISDFlags: 1962289004Sed fputs(xlookup_bits(cloudabi_sdflags, args[sc->offset]), fp); 1963289004Sed break; 1964289004Sed case CloudABISignal: 1965289004Sed fputs(xlookup(cloudabi_signal, args[sc->offset]), fp); 1966289004Sed break; 1967289004Sed case CloudABISockStat: { 1968289004Sed cloudabi_sockstat_t ss; 1969289004Sed if (get_struct(pid, (void *)args[sc->offset], &ss, sizeof(ss)) 1970289004Sed != -1) { 1971289004Sed fprintf(fp, "{ %s, ", xlookup( 1972289004Sed cloudabi_sa_family, ss.ss_sockname.sa_family)); 1973289004Sed fprintf(fp, "%s, ", xlookup( 1974289004Sed cloudabi_sa_family, ss.ss_peername.sa_family)); 1975289004Sed fprintf(fp, "%s, ", xlookup( 1976289004Sed cloudabi_errno, ss.ss_error)); 1977289004Sed fprintf(fp, "%s }", xlookup_bits( 1978289004Sed cloudabi_ssstate, ss.ss_state)); 1979289004Sed } else 1980289004Sed fprintf(fp, "0x%lx", args[sc->offset]); 1981289004Sed break; 1982289004Sed } 1983289004Sed case CloudABISSFlags: 1984289004Sed fputs(xlookup_bits(cloudabi_ssflags, args[sc->offset]), fp); 1985289004Sed break; 1986289004Sed case CloudABITimestamp: 1987289004Sed fprintf(fp, "%lu.%09lus", args[sc->offset] / 1000000000, 1988289004Sed args[sc->offset] % 1000000000); 1989289004Sed break; 1990289004Sed case CloudABIULFlags: 1991289004Sed fputs(xlookup_bits(cloudabi_ulflags, args[sc->offset]), fp); 1992289004Sed break; 1993289004Sed case CloudABIWhence: 1994289004Sed fputs(xlookup(cloudabi_whence, args[sc->offset]), fp); 1995289004Sed break; 1996289004Sed 1997181061Sdes default: 1998181061Sdes errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); 1999181061Sdes } 2000286913Sjhb fclose(fp); 2001181061Sdes return (tmp); 200231567Ssef} 200331567Ssef 200431567Ssef/* 2005295677Sjhb * Print (to outfile) the system call and its arguments. 200631567Ssef */ 200731567Ssefvoid 2008295677Sjhbprint_syscall(struct trussinfo *trussinfo) 2009181061Sdes{ 2010295677Sjhb struct threadinfo *t; 2011295677Sjhb const char *name; 2012295677Sjhb char **s_args; 2013295677Sjhb int i, len, nargs; 2014101283Smdodd 2015295677Sjhb t = trussinfo->curthread; 2016101283Smdodd 2017295677Sjhb name = t->cs.name; 2018295677Sjhb nargs = t->cs.nargs; 2019295677Sjhb s_args = t->cs.s_args; 2020101285Smdodd 2021295930Sjhb len = print_line_prefix(trussinfo); 2022181061Sdes len += fprintf(trussinfo->outfile, "%s(", name); 2023101283Smdodd 2024181061Sdes for (i = 0; i < nargs; i++) { 2025295677Sjhb if (s_args[i] != NULL) 2026181061Sdes len += fprintf(trussinfo->outfile, "%s", s_args[i]); 2027181061Sdes else 2028240005Szont len += fprintf(trussinfo->outfile, 2029240005Szont "<missing argument>"); 2030240005Szont len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ? 2031240005Szont "," : ""); 2032181061Sdes } 2033181061Sdes len += fprintf(trussinfo->outfile, ")"); 2034181061Sdes for (i = 0; i < 6 - (len / 8); i++) 2035181061Sdes fprintf(trussinfo->outfile, "\t"); 203631567Ssef} 203758224Ssef 203858224Ssefvoid 2039295677Sjhbprint_syscall_ret(struct trussinfo *trussinfo, int errorp, long *retval) 2040122348Smarcel{ 2041192025Sdds struct timespec timediff; 2042295677Sjhb struct threadinfo *t; 2043295677Sjhb struct syscall *sc; 2044295931Sjhb int error; 2045181061Sdes 2046295677Sjhb t = trussinfo->curthread; 2047295677Sjhb sc = t->cs.sc; 2048192025Sdds if (trussinfo->flags & COUNTONLY) { 2049295677Sjhb timespecsubt(&t->after, &t->before, &timediff); 2050247338Sdelphij timespecadd(&sc->time, &timediff, &sc->time); 2051192025Sdds sc->ncalls++; 2052192025Sdds if (errorp) 2053192025Sdds sc->nerror++; 2054192025Sdds return; 2055192025Sdds } 2056192025Sdds 2057295677Sjhb print_syscall(trussinfo); 2058181061Sdes fflush(trussinfo->outfile); 2059296571Sjhb 2060296571Sjhb if (retval == NULL) { 2061296571Sjhb /* 2062296571Sjhb * This system call resulted in the current thread's exit, 2063296571Sjhb * so there is no return value or error to display. 2064296571Sjhb */ 2065296571Sjhb fprintf(trussinfo->outfile, "\n"); 2066296571Sjhb return; 2067296571Sjhb } 2068296571Sjhb 2069295931Sjhb if (errorp) { 2070295931Sjhb error = sysdecode_abi_to_freebsd_errno(t->proc->abi->abi, 2071295931Sjhb retval[0]); 2072288424Sjhb fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0], 2073295931Sjhb error == INT_MAX ? "Unknown error" : strerror(error)); 2074295931Sjhb } 2075288424Sjhb#ifndef __LP64__ 2076288832Sbdrewery else if (sc->ret_type == 2) { 2077288424Sjhb off_t off; 2078288424Sjhb 2079288424Sjhb#if _BYTE_ORDER == _LITTLE_ENDIAN 2080288424Sjhb off = (off_t)retval[1] << 32 | retval[0]; 2081288424Sjhb#else 2082288424Sjhb off = (off_t)retval[0] << 32 | retval[1]; 2083288424Sjhb#endif 2084288424Sjhb fprintf(trussinfo->outfile, " = %jd (0x%jx)\n", (intmax_t)off, 2085288424Sjhb (intmax_t)off); 2086181061Sdes } 2087288424Sjhb#endif 2088288424Sjhb else 2089288424Sjhb fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval[0], 2090288424Sjhb retval[0]); 209158224Ssef} 2092192025Sdds 2093192025Sddsvoid 2094192025Sddsprint_summary(struct trussinfo *trussinfo) 2095192025Sdds{ 2096240005Szont struct timespec total = {0, 0}; 2097192025Sdds struct syscall *sc; 2098192025Sdds int ncall, nerror; 2099192025Sdds 2100192025Sdds fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n", 2101240005Szont "syscall", "seconds", "calls", "errors"); 2102192025Sdds ncall = nerror = 0; 2103288832Sbdrewery STAILQ_FOREACH(sc, &syscalls, entries) 2104192025Sdds if (sc->ncalls) { 2105200781Sjh fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n", 2106200781Sjh sc->name, (intmax_t)sc->time.tv_sec, 2107200781Sjh sc->time.tv_nsec, sc->ncalls, sc->nerror); 2108247338Sdelphij timespecadd(&total, &sc->time, &total); 2109192025Sdds ncall += sc->ncalls; 2110192025Sdds nerror += sc->nerror; 2111192025Sdds } 2112192025Sdds fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n", 2113240005Szont "", "-------------", "-------", "-------"); 2114200781Sjh fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n", 2115240005Szont "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror); 2116192025Sdds} 2117