aboutsummaryrefslogtreecommitdiff
path: root/lib/libsysdecode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsysdecode')
-rw-r--r--lib/libsysdecode/Makefile159
-rw-r--r--lib/libsysdecode/Makefile.depend143
-rw-r--r--lib/libsysdecode/errno.c90
-rw-r--r--lib/libsysdecode/flags.c1209
-rw-r--r--lib/libsysdecode/linux.c253
-rw-r--r--lib/libsysdecode/mkioctls106
-rw-r--r--lib/libsysdecode/mklinuxtables113
-rw-r--r--lib/libsysdecode/mktables189
-rw-r--r--lib/libsysdecode/signal.c139
-rw-r--r--lib/libsysdecode/support.c165
-rw-r--r--lib/libsysdecode/support.h62
-rw-r--r--lib/libsysdecode/syscallnames.c96
-rw-r--r--lib/libsysdecode/sysdecode.382
-rw-r--r--lib/libsysdecode/sysdecode.h152
-rw-r--r--lib/libsysdecode/sysdecode_abi_to_freebsd_errno.392
-rw-r--r--lib/libsysdecode/sysdecode_cap_rights.366
-rw-r--r--lib/libsysdecode/sysdecode_cmsg_type.350
-rw-r--r--lib/libsysdecode/sysdecode_enum.3259
-rw-r--r--lib/libsysdecode/sysdecode_fcntl_arg.3117
-rw-r--r--lib/libsysdecode/sysdecode_ioctlname.355
-rw-r--r--lib/libsysdecode/sysdecode_kevent.3120
-rw-r--r--lib/libsysdecode/sysdecode_mask.3250
-rw-r--r--lib/libsysdecode/sysdecode_quotactl_cmd.388
-rw-r--r--lib/libsysdecode/sysdecode_sctp_sinfo_flags.350
-rw-r--r--lib/libsysdecode/sysdecode_sigcode.378
-rw-r--r--lib/libsysdecode/sysdecode_socket_protocol.349
-rw-r--r--lib/libsysdecode/sysdecode_sockopt_name.356
-rw-r--r--lib/libsysdecode/sysdecode_syscallname.366
-rw-r--r--lib/libsysdecode/sysdecode_utrace.371
-rw-r--r--lib/libsysdecode/tests/Makefile5
-rw-r--r--lib/libsysdecode/tests/sysdecode_test.c152
-rw-r--r--lib/libsysdecode/utrace.c211
32 files changed, 4793 insertions, 0 deletions
diff --git a/lib/libsysdecode/Makefile b/lib/libsysdecode/Makefile
new file mode 100644
index 000000000000..11f45355b8e2
--- /dev/null
+++ b/lib/libsysdecode/Makefile
@@ -0,0 +1,159 @@
+.include <src.opts.mk>
+
+LIB= sysdecode
+
+SRCS= errno.c flags.c ioctl.c signal.c syscallnames.c utrace.c support.c
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \
+ ${MACHINE_CPUARCH} == "i386"
+SRCS+= linux.c
+.endif
+INCS= sysdecode.h
+
+CFLAGS+= -I${.OBJDIR}
+CFLAGS+= -I${SRCTOP}/sys
+CFLAGS+= -I${SRCTOP}/libexec/rtld-elf
+
+MAN= sysdecode.3 \
+ sysdecode_abi_to_freebsd_errno.3 \
+ sysdecode_cap_rights.3 \
+ sysdecode_cmsg_type.3 \
+ sysdecode_enum.3 \
+ sysdecode_fcntl_arg.3 \
+ sysdecode_kevent.3 \
+ sysdecode_ioctlname.3 \
+ sysdecode_mask.3 \
+ sysdecode_quotactl_cmd.3 \
+ sysdecode_sctp_sinfo_flags.3 \
+ sysdecode_sigcode.3 \
+ sysdecode_sockopt_name.3 \
+ sysdecode_socket_protocol.3 \
+ sysdecode_syscallname.3 \
+ sysdecode_utrace.3
+MLINKS= sysdecode_abi_to_freebsd_errno.3 sysdecode_freebsd_to_abi_errno.3
+MLINKS+=sysdecode_enum.3 sysdecode_acltype.3 \
+ sysdecode_enum.3 sysdecode_atfd.3 \
+ sysdecode_enum.3 sysdecode_extattrnamespace.3 \
+ sysdecode_enum.3 sysdecode_fadvice.3 \
+ sysdecode_enum.3 sysdecode_fcntl_cmd.3 \
+ sysdecode_enum.3 sysdecode_getfsstat_mode.3 \
+ sysdecode_enum.3 sysdecode_getrusage_who.3 \
+ sysdecode_enum.3 sysdecode_idtype.3 \
+ sysdecode_enum.3 sysdecode_ipproto.3 \
+ sysdecode_enum.3 sysdecode_kldsym_cmd.3 \
+ sysdecode_enum.3 sysdecode_kldunload_flags.3 \
+ sysdecode_enum.3 sysdecode_lio_listio_mode.3 \
+ sysdecode_enum.3 sysdecode_madvice.3 \
+ sysdecode_enum.3 sysdecode_minherit_flags.3 \
+ sysdecode_enum.3 sysdecode_msgctl_cmd.3 \
+ sysdecode_enum.3 sysdecode_nfssvc_flags.3 \
+ sysdecode_enum.3 sysdecode_pathconf_name.3 \
+ sysdecode_enum.3 sysdecode_prio_which.3 \
+ sysdecode_enum.3 sysdecode_procctl_cmd.3 \
+ sysdecode_enum.3 sysdecode_ptrace_request.3 \
+ sysdecode_enum.3 sysdecode_rlimit.3 \
+ sysdecode_enum.3 sysdecode_rtprio_function.3 \
+ sysdecode_enum.3 sysdecode_scheduler_policy.3 \
+ sysdecode_enum.3 sysdecode_sctp_pr_policy.3 \
+ sysdecode_enum.3 sysdecode_semctl_cmd.3 \
+ sysdecode_enum.3 sysdecode_shmctl_cmd.3 \
+ sysdecode_enum.3 sysdecode_shutdown_how.3 \
+ sysdecode_enum.3 sysdecode_sigbus_code.3 \
+ sysdecode_enum.3 sysdecode_sigchld_code.3 \
+ sysdecode_enum.3 sysdecode_sigfpe_code.3 \
+ sysdecode_enum.3 sysdecode_sigill_code.3 \
+ sysdecode_enum.3 sysdecode_signal.3 \
+ sysdecode_enum.3 sysdecode_sigprocmask_how.3 \
+ sysdecode_enum.3 sysdecode_sigsegv_code.3 \
+ sysdecode_enum.3 sysdecode_sigtrap_code.3 \
+ sysdecode_enum.3 sysdecode_sockaddr_family.3 \
+ sysdecode_enum.3 sysdecode_socketdomain.3 \
+ sysdecode_enum.3 sysdecode_sockettype.3 \
+ sysdecode_enum.3 sysdecode_sockopt_level.3 \
+ sysdecode_enum.3 sysdecode_sysarch_number.3 \
+ sysdecode_enum.3 sysdecode_umtx_op.3 \
+ sysdecode_enum.3 sysdecode_vmresult.3 \
+ sysdecode_enum.3 sysdecode_whence.3
+MLINKS+=sysdecode_fcntl_arg.3 sysdecode_fcntl_arg_p.3
+MLINKS+=sysdecode_kevent.3 sysdecode_kevent_fflags.3 \
+ sysdecode_kevent.3 sysdecode_kevent_filter.3 \
+ sysdecode_kevent.3 sysdecode_kevent_flags.3
+MLINKS+=sysdecode_mask.3 sysdecode_accessmode.3 \
+ sysdecode_mask.3 sysdecode_atflags.3 \
+ sysdecode_mask.3 sysdecode_capfcntlrights.3 \
+ sysdecode_mask.3 sysdecode_fcntl_fileflags.3 \
+ sysdecode_mask.3 sysdecode_fileflags.3 \
+ sysdecode_mask.3 sysdecode_filemode.3 \
+ sysdecode_mask.3 sysdecode_flock_operation.3 \
+ sysdecode_mask.3 sysdecode_inotifyflags.3 \
+ sysdecode_mask.3 sysdecode_mlockall_flags.3 \
+ sysdecode_mask.3 sysdecode_mmap_flags.3 \
+ sysdecode_mask.3 sysdecode_mmap_prot.3 \
+ sysdecode_mask.3 sysdecode_mount_flags.3 \
+ sysdecode_mask.3 sysdecode_msg_flags.3 \
+ sysdecode_mask.3 sysdecode_msync_flags.3 \
+ sysdecode_mask.3 sysdecode_open_flags.3 \
+ sysdecode_mask.3 sysdecode_pipe2_flags.3 \
+ sysdecode_mask.3 sysdecode_pollfd_events.3 \
+ sysdecode_mask.3 sysdecode_reboot_howto.3 \
+ sysdecode_mask.3 sysdecode_rfork_flags.3 \
+ sysdecode_mask.3 sysdecode_semget_flags.3 \
+ sysdecode_mask.3 sysdecode_sendfile_flags.3 \
+ sysdecode_mask.3 sysdecode_shmat_flags.3 \
+ sysdecode_mask.3 sysdecode_sctp_nxt_flags.3 \
+ sysdecode_mask.3 sysdecode_sctp_rcv_flags.3 \
+ sysdecode_mask.3 sysdecode_sctp_snd_flags.3 \
+ sysdecode_mask.3 sysdecode_socket_type.3 \
+ sysdecode_mask.3 sysdecode_thr_create_flags.3 \
+ sysdecode_mask.3 sysdecode_umtx_cvwait_flags.3 \
+ sysdecode_mask.3 sysdecode_umtx_rwlock_flags.3 \
+ sysdecode_mask.3 sysdecode_vmprot.3 \
+ sysdecode_mask.3 sysdecode_wait4_options.3 \
+ sysdecode_mask.3 sysdecode_wait6_options.3
+
+CLEANFILES= ioctl.c ioctl.c.tmp tables.h tables_linux.h
+
+# XXX: The flags should come from bsd.compat.mk / Makefile.libcompat
+.if ${COMPAT_LIBCOMPAT:U} == "32"
+CPP+= -m32
+.endif
+
+.if ${MK_PF} != "no"
+CFLAGS+=-DPF
+.endif
+
+# Workaround duplicate declarations in <netinet/ip_compat.h>
+CFLAGS.gcc.ioctl.c+= -Wno-redundant-decls
+
+CFLAGS.gcc+= ${CFLAGS.gcc.${.IMPSRC}}
+
+DEPENDOBJS+= tables.h tables_linux.h
+.if ${MK_DIRDEPS_BUILD} == "yes"
+MKTABLES_INCLUDEDIR= ${STAGE_INCLUDEDIR}
+.else
+MKTABLES_INCLUDEDIR= ${SYSROOT:U${DESTDIR}}${INCLUDEDIR}
+.endif
+tables.h: mktables
+ sh ${.CURDIR}/mktables ${MKTABLES_INCLUDEDIR} ${.TARGET}
+tables_linux.h: mklinuxtables
+ sh ${.CURDIR}/mklinuxtables ${SRCTOP}/sys ${.TARGET}
+
+# mkioctls runs find(1) for headers so needs to rebuild every time. This used
+# to be a hack only done in buildworld.
+.if !defined(_SKIP_BUILD)
+ioctl.c.tmp: .PHONY
+.endif
+ioctl.c.tmp: mkioctls .META
+ env CPP="${CPP}" MK_PF="${MK_PF}" \
+ /bin/sh ${.CURDIR}/mkioctls ${SYSROOT:U${DESTDIR}}${INCLUDEDIR} > ${.TARGET}
+
+ioctl.c: ioctl.c.tmp
+ if [ ! -e ${.TARGET} ] || ! cmp -s ${.TARGET} ${.TARGET}.tmp; then \
+ mv -f ${.TARGET}.tmp ${.TARGET}; \
+ fi
+
+beforedepend: ioctl.c tables.h tables_linux.h
+
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+= tests
+
+.include <bsd.lib.mk>
diff --git a/lib/libsysdecode/Makefile.depend b/lib/libsysdecode/Makefile.depend
new file mode 100644
index 000000000000..1c40e21d361d
--- /dev/null
+++ b/lib/libsysdecode/Makefile.depend
@@ -0,0 +1,143 @@
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+ cddl/lib/libdtrace \
+ cddl/lib/libnvpair \
+ cddl/lib/libtpool \
+ cddl/lib/libzfs \
+ cddl/lib/libzfs_core \
+ cddl/lib/libzfsbootenv \
+ cddl/lib/libzutil \
+ cddl/usr.bin/zinject \
+ cddl/usr.sbin/zdb \
+ gnu/lib/libdialog \
+ include \
+ include/arpa \
+ include/gssapi \
+ include/protocols \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libgssapi_krb5 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkadm5clnt \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkdc \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/atf/libatf-c \
+ lib/lib80211 \
+ lib/lib9p \
+ lib/libalias/libalias \
+ lib/libarchive \
+ lib/libbe \
+ lib/libbegemot \
+ lib/libblacklist \
+ lib/libblocksruntime \
+ lib/libbluetooth \
+ lib/libbsddialog \
+ lib/libbsdstat \
+ lib/libbsm \
+ lib/libbsnmp/libbsnmp \
+ lib/libbz2 \
+ lib/libc \
+ lib/libc++ \
+ lib/libcalendar \
+ lib/libcam \
+ lib/libcapsicum \
+ lib/libcasper/libcasper \
+ lib/libcasper/services/cap_dns \
+ lib/libcasper/services/cap_fileargs \
+ lib/libcasper/services/cap_grp \
+ lib/libcasper/services/cap_net \
+ lib/libcasper/services/cap_netdb \
+ lib/libcasper/services/cap_pwd \
+ lib/libcasper/services/cap_sysctl \
+ lib/libcasper/services/cap_syslog \
+ lib/libcom_err \
+ lib/libcompiler_rt \
+ lib/libcuse \
+ lib/libdevctl \
+ lib/libdevdctl \
+ lib/libdevinfo \
+ lib/libdevstat \
+ lib/libdpv \
+ lib/libdwarf \
+ lib/libedit \
+ lib/libedit/readline \
+ lib/libefivar \
+ lib/libelf \
+ lib/libevent1 \
+ lib/libexecinfo \
+ lib/libexpat \
+ lib/libfetch \
+ lib/libfigpar \
+ lib/libgeom \
+ lib/libgpio \
+ lib/libjail \
+ lib/libkvm \
+ lib/liblzma \
+ lib/libmagic \
+ lib/libmd \
+ lib/libmemstat \
+ lib/libmilter \
+ lib/libmixer \
+ lib/libmp \
+ lib/libmt \
+ lib/libnetgraph \
+ lib/libpam/libpam \
+ lib/libpathconv \
+ lib/libpcap \
+ lib/libpmc \
+ lib/libproc \
+ lib/libprocstat \
+ lib/libradius \
+ lib/librss \
+ lib/librtld_db \
+ lib/libsdp \
+ lib/libsecureboot \
+ lib/libsqlite3 \
+ lib/libstdthreads \
+ lib/libtacplus \
+ lib/libthread_db \
+ lib/libucl \
+ lib/libufs \
+ lib/libugidfw \
+ lib/libulog \
+ lib/libusb \
+ lib/libusbhid \
+ lib/libutil \
+ lib/libveriexec \
+ lib/libvgl \
+ lib/libvmmapi \
+ lib/libwrap \
+ lib/libxo/libxo \
+ lib/libypclnt \
+ lib/libz \
+ lib/libzstd \
+ lib/msun \
+ lib/ncurses/form \
+ lib/ncurses/menu \
+ lib/ncurses/panel \
+ lib/ncurses/tinfo \
+ lib/ofed/include \
+ secure/lib/libcrypto \
+ usr.bin/awk.host \
+ usr.bin/lex \
+ usr.sbin/bsnmpd/modules \
+ usr.sbin/bsnmpd/modules/snmp_bridge \
+ usr.sbin/bsnmpd/modules/snmp_mibII \
+ usr.sbin/bsnmpd/modules/snmp_netgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libsysdecode/errno.c b/lib/libsysdecode/errno.c
new file mode 100644
index 000000000000..366f3d9a6f33
--- /dev/null
+++ b/lib/libsysdecode/errno.c
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2015 John H. Baldwin <jhb@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/acl.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sysdecode.h>
+
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+#include <compat/linux/linux_errno.h>
+#include <compat/linux/linux_errno.inc>
+#endif
+
+int
+sysdecode_abi_to_freebsd_errno(enum sysdecode_abi abi, int error)
+{
+
+ switch (abi) {
+ case SYSDECODE_ABI_FREEBSD:
+ case SYSDECODE_ABI_FREEBSD32:
+ return (error);
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+ case SYSDECODE_ABI_LINUX:
+ case SYSDECODE_ABI_LINUX32: {
+ unsigned int i;
+
+ /*
+ * This is imprecise since it returns the first
+ * matching errno.
+ */
+ for (i = 0; i < nitems(linux_errtbl); i++) {
+ if (error == linux_errtbl[i])
+ return (i);
+ }
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ return (INT_MAX);
+}
+
+int
+sysdecode_freebsd_to_abi_errno(enum sysdecode_abi abi, int error)
+{
+
+ switch (abi) {
+ case SYSDECODE_ABI_FREEBSD:
+ case SYSDECODE_ABI_FREEBSD32:
+ return (error);
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+ case SYSDECODE_ABI_LINUX:
+ case SYSDECODE_ABI_LINUX32:
+ if (error >= 0 && error <= ELAST)
+ return (linux_errtbl[error]);
+ break;
+#endif
+ default:
+ break;
+ }
+ return (INT_MAX);
+}
+
diff --git a/lib/libsysdecode/flags.c b/lib/libsysdecode/flags.c
new file mode 100644
index 000000000000..f8e26e6a9dae
--- /dev/null
+++ b/lib/libsysdecode/flags.c
@@ -0,0 +1,1209 @@
+/*
+ * Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define L2CAP_SOCKET_CHECKED
+
+#include <sys/types.h>
+#include <sys/acl.h>
+#include <sys/capsicum.h>
+#include <sys/event.h>
+#include <sys/extattr.h>
+#include <sys/inotify.h>
+#include <sys/linker.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/poll.h>
+#include <sys/procctl.h>
+#include <sys/ptrace.h>
+#include <sys/reboot.h>
+#include <sys/resource.h>
+#include <sys/rtprio.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/thr.h>
+#include <sys/umtx.h>
+#include <machine/sysarch.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/udplite.h>
+#include <nfsserver/nfs.h>
+#include <ufs/ufs/quota.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <aio.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sysdecode.h>
+#include <unistd.h>
+#include <sys/bitstring.h>
+#include <netgraph/bluetooth/include/ng_hci.h>
+#include <netgraph/bluetooth/include/ng_l2cap.h>
+#include <netgraph/bluetooth/include/ng_btsocket.h>
+
+#include "support.h"
+
+#define X(a) { a, #a },
+#define XEND { 0, NULL }
+
+#define TABLE_START(n) static struct name_table n[] = {
+#define TABLE_ENTRY X
+#define TABLE_END XEND };
+
+#include "tables.h"
+
+#undef TABLE_START
+#undef TABLE_ENTRY
+#undef TABLE_END
+
+const char *
+sysdecode_atfd(int fd)
+{
+
+ if (fd == AT_FDCWD)
+ return ("AT_FDCWD");
+ return (NULL);
+}
+
+bool
+sysdecode_atflags(FILE *fp, int flag, int *rem)
+{
+
+ return (print_mask_int(fp, atflags, flag, rem));
+}
+
+static struct name_table semctlops[] = {
+ X(GETNCNT) X(GETPID) X(GETVAL) X(GETALL) X(GETZCNT) X(SETVAL) X(SETALL)
+ X(IPC_RMID) X(IPC_SET) X(IPC_STAT) XEND
+};
+
+const char *
+sysdecode_semctl_cmd(int cmd)
+{
+
+ return (lookup_value(semctlops, cmd));
+}
+
+static struct name_table shmctlops[] = {
+ X(IPC_RMID) X(IPC_SET) X(IPC_STAT) XEND
+};
+
+const char *
+sysdecode_shmctl_cmd(int cmd)
+{
+
+ return (lookup_value(shmctlops, cmd));
+}
+
+const char *
+sysdecode_msgctl_cmd(int cmd)
+{
+
+ return (sysdecode_shmctl_cmd(cmd));
+}
+
+static struct name_table semgetflags[] = {
+ X(IPC_CREAT) X(IPC_EXCL) X(SEM_R) X(SEM_A) X((SEM_R>>3)) X((SEM_A>>3))
+ X((SEM_R>>6)) X((SEM_A>>6)) XEND
+};
+
+bool
+sysdecode_semget_flags(FILE *fp, int flag, int *rem)
+{
+
+ return (print_mask_int(fp, semgetflags, flag, rem));
+}
+
+static struct name_table idtypes[] = {
+ X(P_PID) X(P_PPID) X(P_PGID) X(P_SID) X(P_CID) X(P_UID) X(P_GID)
+ X(P_ALL) X(P_LWPID) X(P_TASKID) X(P_PROJID) X(P_POOLID) X(P_JAILID)
+ X(P_CTID) X(P_CPUID) X(P_PSETID) XEND
+};
+
+/* XXX: idtype is really an idtype_t */
+const char *
+sysdecode_idtype(int idtype)
+{
+
+ return (lookup_value(idtypes, idtype));
+}
+
+/*
+ * [g|s]etsockopt's level argument can either be SOL_SOCKET or a
+ * protocol-specific value.
+ */
+const char *
+sysdecode_sockopt_level(int level)
+{
+ const char *str;
+
+ if (level == SOL_SOCKET)
+ return ("SOL_SOCKET");
+
+ /* SOL_* constants for Bluetooth sockets. */
+ str = lookup_value(ngbtsolevel, level);
+ if (str != NULL)
+ return (str);
+
+ /*
+ * IP and Infiniband sockets use IP protocols as levels. Not all
+ * protocols are valid but it is simpler to just allow all of them.
+ *
+ * XXX: IPPROTO_IP == 0, but UNIX domain sockets use a level of 0
+ * for private options.
+ */
+ str = sysdecode_ipproto(level);
+ if (str != NULL)
+ return (str);
+
+ return (NULL);
+}
+
+bool
+sysdecode_vmprot(FILE *fp, int type, int *rem)
+{
+
+ return (print_mask_int(fp, vmprot, type, rem));
+}
+
+static struct name_table sockflags[] = {
+ X(SOCK_CLOEXEC) X(SOCK_CLOFORK) X(SOCK_NONBLOCK) XEND
+};
+
+bool
+sysdecode_socket_type(FILE *fp, int type, int *rem)
+{
+ const char *str;
+ uintmax_t val;
+ bool printed;
+
+ str = lookup_value(socktype,
+ type & ~(SOCK_CLOEXEC | SOCK_CLOFORK | SOCK_NONBLOCK));
+ if (str != NULL) {
+ fputs(str, fp);
+ *rem = 0;
+ printed = true;
+ } else {
+ *rem = type & ~(SOCK_CLOEXEC | SOCK_CLOFORK | SOCK_NONBLOCK);
+ printed = false;
+ }
+ val = type & (SOCK_CLOEXEC | SOCK_CLOFORK | SOCK_NONBLOCK);
+ print_mask_part(fp, sockflags, &val, &printed);
+ return (printed);
+}
+
+bool
+sysdecode_access_mode(FILE *fp, int mode, int *rem)
+{
+
+ return (print_mask_int(fp, accessmode, mode, rem));
+}
+
+/* XXX: 'type' is really an acl_type_t. */
+const char *
+sysdecode_acltype(int type)
+{
+
+ return (lookup_value(acltype, type));
+}
+
+bool
+sysdecode_cap_fcntlrights(FILE *fp, uint32_t rights, uint32_t *rem)
+{
+
+ return (print_mask_int(fp, capfcntl, rights, rem));
+}
+
+bool
+sysdecode_close_range_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, closerangeflags, flags, rem));
+}
+
+const char *
+sysdecode_extattrnamespace(int namespace)
+{
+
+ return (lookup_value(extattrns, namespace));
+}
+
+const char *
+sysdecode_fadvice(int advice)
+{
+
+ return (lookup_value(fadvisebehav, advice));
+}
+
+bool
+sysdecode_open_flags(FILE *fp, int flags, int *rem)
+{
+ bool printed;
+ int mode;
+ uintmax_t val;
+
+ mode = flags & O_ACCMODE;
+ flags &= ~O_ACCMODE;
+ switch (mode) {
+ case O_RDONLY:
+ if (flags & O_EXEC) {
+ flags &= ~O_EXEC;
+ fputs("O_EXEC", fp);
+ } else
+ fputs("O_RDONLY", fp);
+ printed = true;
+ mode = 0;
+ break;
+ case O_WRONLY:
+ fputs("O_WRONLY", fp);
+ printed = true;
+ mode = 0;
+ break;
+ case O_RDWR:
+ fputs("O_RDWR", fp);
+ printed = true;
+ mode = 0;
+ break;
+ default:
+ printed = false;
+ }
+ val = (unsigned)flags;
+ print_mask_part(fp, openflags, &val, &printed);
+ if (rem != NULL)
+ *rem = val | mode;
+ return (printed);
+}
+
+bool
+sysdecode_fcntl_fileflags(FILE *fp, int flags, int *rem)
+{
+ bool printed;
+ int oflags;
+
+ /*
+ * The file flags used with F_GETFL/F_SETFL mostly match the
+ * flags passed to open(2). However, a few open-only flag
+ * bits have been repurposed for fcntl-only flags.
+ */
+ oflags = flags & ~(O_NOFOLLOW | FRDAHEAD);
+ printed = sysdecode_open_flags(fp, oflags, rem);
+ if (flags & O_NOFOLLOW) {
+ fprintf(fp, "%sFPOIXSHM", printed ? "|" : "");
+ printed = true;
+ }
+ if (flags & FRDAHEAD) {
+ fprintf(fp, "%sFRDAHEAD", printed ? "|" : "");
+ printed = true;
+ }
+ return (printed);
+}
+
+bool
+sysdecode_flock_operation(FILE *fp, int operation, int *rem)
+{
+
+ return (print_mask_int(fp, flockops, operation, rem));
+}
+
+static struct name_table getfsstatmode[] = {
+ X(MNT_WAIT) X(MNT_NOWAIT) XEND
+};
+
+const char *
+sysdecode_getfsstat_mode(int mode)
+{
+
+ return (lookup_value(getfsstatmode, mode));
+}
+
+const char *
+sysdecode_getrusage_who(int who)
+{
+
+ return (lookup_value(rusage, who));
+}
+
+bool
+sysdecode_inotifyflags(FILE *fp, int flag, int *rem)
+{
+
+ return (print_mask_int(fp, inotifyflags, flag, rem));
+}
+
+static struct name_table kevent_user_ffctrl[] = {
+ X(NOTE_FFNOP) X(NOTE_FFAND) X(NOTE_FFOR) X(NOTE_FFCOPY)
+ XEND
+};
+
+static struct name_table kevent_rdwr_fflags[] = {
+ X(NOTE_LOWAT) X(NOTE_FILE_POLL) XEND
+};
+
+static struct name_table kevent_vnode_fflags[] = {
+ X(NOTE_DELETE) X(NOTE_WRITE) X(NOTE_EXTEND) X(NOTE_ATTRIB)
+ X(NOTE_LINK) X(NOTE_RENAME) X(NOTE_REVOKE) X(NOTE_OPEN) X(NOTE_CLOSE)
+ X(NOTE_CLOSE_WRITE) X(NOTE_READ) XEND
+};
+
+static struct name_table kevent_proc_fflags[] = {
+ X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_TRACK) X(NOTE_TRACKERR)
+ X(NOTE_CHILD) XEND
+};
+
+static struct name_table kevent_timer_fflags[] = {
+ X(NOTE_SECONDS) X(NOTE_MSECONDS) X(NOTE_USECONDS) X(NOTE_NSECONDS)
+ X(NOTE_ABSTIME) XEND
+};
+
+void
+sysdecode_kevent_fflags(FILE *fp, short filter, int fflags, int base)
+{
+ int rem;
+
+ if (fflags == 0) {
+ fputs("0", fp);
+ return;
+ }
+
+ switch (filter) {
+ case EVFILT_READ:
+ case EVFILT_WRITE:
+ if (!print_mask_int(fp, kevent_rdwr_fflags, fflags, &rem))
+ fprintf(fp, "%#x", rem);
+ else if (rem != 0)
+ fprintf(fp, "|%#x", rem);
+ break;
+ case EVFILT_VNODE:
+ if (!print_mask_int(fp, kevent_vnode_fflags, fflags, &rem))
+ fprintf(fp, "%#x", rem);
+ else if (rem != 0)
+ fprintf(fp, "|%#x", rem);
+ break;
+ case EVFILT_PROC:
+ case EVFILT_PROCDESC:
+ if (!print_mask_int(fp, kevent_proc_fflags, fflags, &rem))
+ fprintf(fp, "%#x", rem);
+ else if (rem != 0)
+ fprintf(fp, "|%#x", rem);
+ break;
+ case EVFILT_TIMER:
+ if (!print_mask_int(fp, kevent_timer_fflags, fflags, &rem))
+ fprintf(fp, "%#x", rem);
+ else if (rem != 0)
+ fprintf(fp, "|%#x", rem);
+ break;
+ case EVFILT_USER: {
+ unsigned int ctrl, data;
+
+ ctrl = fflags & NOTE_FFCTRLMASK;
+ data = fflags & NOTE_FFLAGSMASK;
+
+ if (fflags & NOTE_TRIGGER) {
+ fputs("NOTE_TRIGGER", fp);
+ if (fflags == NOTE_TRIGGER)
+ return;
+ fputc('|', fp);
+ }
+
+ /*
+ * An event with 'ctrl' == NOTE_FFNOP is either a reported
+ * (output) event for which only 'data' should be output
+ * or a pointless input event. Assume that pointless
+ * input events don't occur in practice. An event with
+ * NOTE_TRIGGER is always an input event.
+ */
+ if (ctrl != NOTE_FFNOP || fflags & NOTE_TRIGGER) {
+ fprintf(fp, "%s|%#x",
+ lookup_value(kevent_user_ffctrl, ctrl), data);
+ } else {
+ print_integer(fp, data, base);
+ }
+ break;
+ }
+ default:
+ print_integer(fp, fflags, base);
+ break;
+ }
+}
+
+bool
+sysdecode_kevent_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, keventflags, flags, rem));
+}
+
+const char *
+sysdecode_kevent_filter(int filter)
+{
+
+ return (lookup_value(keventfilters, filter));
+}
+
+const char *
+sysdecode_kldsym_cmd(int cmd)
+{
+
+ return (lookup_value(kldsymcmd, cmd));
+}
+
+const char *
+sysdecode_kldunload_flags(int flags)
+{
+
+ return (lookup_value(kldunloadfflags, flags));
+}
+
+const char *
+sysdecode_lio_listio_mode(int mode)
+{
+
+ return (lookup_value(lio_listiomodes, mode));
+}
+
+const char *
+sysdecode_madvice(int advice)
+{
+
+ return (lookup_value(madvisebehav, advice));
+}
+
+const char *
+sysdecode_minherit_inherit(int inherit)
+{
+
+ return (lookup_value(minheritflags, inherit));
+}
+
+bool
+sysdecode_mlockall_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, mlockallflags, flags, rem));
+}
+
+bool
+sysdecode_mmap_prot(FILE *fp, int prot, int *rem)
+{
+ int protm;
+ bool printed;
+
+ printed = false;
+ protm = PROT_MAX_EXTRACT(prot);
+ prot &= ~PROT_MAX(protm);
+ if (protm != 0) {
+ fputs("PROT_MAX(", fp);
+ printed = print_mask_int(fp, mmapprot, protm, rem);
+ fputs(")|", fp);
+ }
+ return (print_mask_int(fp, mmapprot, prot, rem) || printed);
+}
+
+bool
+sysdecode_fileflags(FILE *fp, fflags_t flags, fflags_t *rem)
+{
+
+ return (print_mask_0(fp, fileflags, flags, rem));
+}
+
+bool
+sysdecode_filemode(FILE *fp, int mode, int *rem)
+{
+
+ return (print_mask_0(fp, filemode, mode, rem));
+}
+
+bool
+sysdecode_mount_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, mountflags, flags, rem));
+}
+
+bool
+sysdecode_msync_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, msyncflags, flags, rem));
+}
+
+const char *
+sysdecode_nfssvc_flags(int flags)
+{
+
+ return (lookup_value(nfssvcflags, flags));
+}
+
+static struct name_table pipe2flags[] = {
+ X(O_CLOEXEC) X(O_CLOFORK) X(O_NONBLOCK) XEND
+};
+
+bool
+sysdecode_pipe2_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_0(fp, pipe2flags, flags, rem));
+}
+
+bool
+sysdecode_pollfd_events(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, pollfdevents, flags, rem));
+}
+
+const char *
+sysdecode_prio_which(int which)
+{
+
+ return (lookup_value(prio, which));
+}
+
+const char *
+sysdecode_procctl_cmd(int cmd)
+{
+
+ return (lookup_value(procctlcmd, cmd));
+}
+
+const char *
+sysdecode_ptrace_request(int request)
+{
+
+ return (lookup_value(ptraceop, request));
+}
+
+static struct name_table quotatypes[] = {
+ X(GRPQUOTA) X(USRQUOTA) XEND
+};
+
+bool
+sysdecode_quotactl_cmd(FILE *fp, int cmd)
+{
+ const char *primary, *type;
+
+ primary = lookup_value(quotactlcmds, cmd >> SUBCMDSHIFT);
+ if (primary == NULL)
+ return (false);
+ fprintf(fp, "QCMD(%s,", primary);
+ type = lookup_value(quotatypes, cmd & SUBCMDMASK);
+ if (type != NULL)
+ fprintf(fp, "%s", type);
+ else
+ fprintf(fp, "%#x", cmd & SUBCMDMASK);
+ fprintf(fp, ")");
+ return (true);
+}
+
+bool
+sysdecode_reboot_howto(FILE *fp, int howto, int *rem)
+{
+ bool printed;
+
+ /*
+ * RB_AUTOBOOT is special in that its value is zero, but it is
+ * also an implied argument if a different operation is not
+ * requested via RB_HALT, RB_POWERCYCLE, RB_POWEROFF, or
+ * RB_REROOT.
+ */
+ if (howto != 0 && (howto & (RB_HALT | RB_POWEROFF | RB_REROOT |
+ RB_POWERCYCLE)) == 0) {
+ fputs("RB_AUTOBOOT|", fp);
+ printed = true;
+ } else
+ printed = false;
+ return (print_mask_int(fp, rebootopt, howto, rem) || printed);
+}
+
+bool
+sysdecode_rfork_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, rforkflags, flags, rem));
+}
+
+const char *
+sysdecode_rlimit(int resource)
+{
+
+ return (lookup_value(rlimit, resource));
+}
+
+const char *
+sysdecode_scheduler_policy(int policy)
+{
+
+ return (lookup_value(schedpolicy, policy));
+}
+
+bool
+sysdecode_sendfile_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, sendfileflags, flags, rem));
+}
+
+bool
+sysdecode_shmat_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, shmatflags, flags, rem));
+}
+
+const char *
+sysdecode_shutdown_how(int how)
+{
+
+ return (lookup_value(shutdownhow, how));
+}
+
+const char *
+sysdecode_sigbus_code(int si_code)
+{
+
+ return (lookup_value(sigbuscode, si_code));
+}
+
+const char *
+sysdecode_sigchld_code(int si_code)
+{
+
+ return (lookup_value(sigchldcode, si_code));
+}
+
+const char *
+sysdecode_sigfpe_code(int si_code)
+{
+
+ return (lookup_value(sigfpecode, si_code));
+}
+
+const char *
+sysdecode_sigill_code(int si_code)
+{
+
+ return (lookup_value(sigillcode, si_code));
+}
+
+const char *
+sysdecode_sigsegv_code(int si_code)
+{
+
+ return (lookup_value(sigsegvcode, si_code));
+}
+
+const char *
+sysdecode_sigtrap_code(int si_code)
+{
+
+ return (lookup_value(sigtrapcode, si_code));
+}
+
+const char *
+sysdecode_sigprocmask_how(int how)
+{
+
+ return (lookup_value(sigprocmaskhow, how));
+}
+
+const char *
+sysdecode_socketdomain(int domain)
+{
+
+ return (lookup_value(sockdomain, domain));
+}
+
+const char *
+sysdecode_socket_protocol(int domain, int protocol)
+{
+
+ switch (domain) {
+ case PF_INET:
+ case PF_INET6:
+ return (lookup_value(sockipproto, protocol));
+ default:
+ return (NULL);
+ }
+}
+
+const char *
+sysdecode_sockaddr_family(int sa_family)
+{
+
+ return (lookup_value(sockfamily, sa_family));
+}
+
+const char *
+sysdecode_ipproto(int protocol)
+{
+
+ return (lookup_value(sockipproto, protocol));
+}
+
+const char *
+sysdecode_sockopt_name(int level, int optname)
+{
+
+ if (level == SOL_SOCKET)
+ return (lookup_value(sockopt, optname));
+ if (level == IPPROTO_IP)
+ /* XXX: UNIX domain socket options use a level of 0 also. */
+ return (lookup_value(sockoptip, optname));
+ if (level == IPPROTO_IPV6)
+ return (lookup_value(sockoptipv6, optname));
+ if (level == IPPROTO_SCTP)
+ return (lookup_value(sockoptsctp, optname));
+ if (level == IPPROTO_TCP)
+ return (lookup_value(sockopttcp, optname));
+ if (level == IPPROTO_UDP)
+ return (lookup_value(sockoptudp, optname));
+ if (level == IPPROTO_UDPLITE)
+ return (lookup_value(sockoptudplite, optname));
+ return (NULL);
+}
+
+bool
+sysdecode_thr_create_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, thrcreateflags, flags, rem));
+}
+
+const char *
+sysdecode_umtx_op(int op)
+{
+
+ return (lookup_value(umtxop, op));
+}
+
+bool
+sysdecode_umtx_op_flags(FILE *fp, int op, int *rem)
+{
+ uintmax_t val;
+ bool printed;
+
+ printed = false;
+ val = (unsigned)op;
+ print_mask_part(fp, umtxopflags, &val, &printed);
+ if (rem != NULL)
+ *rem = val;
+ return (printed);
+}
+
+const char *
+sysdecode_vmresult(int result)
+{
+
+ return (lookup_value(vmresult, result));
+}
+
+bool
+sysdecode_wait4_options(FILE *fp, int options, int *rem)
+{
+ bool printed;
+ int opt6;
+
+ /* A flags value of 0 is normal. */
+ if (options == 0) {
+ fputs("0", fp);
+ if (rem != NULL)
+ *rem = 0;
+ return (true);
+ }
+
+ /*
+ * These flags are implicit and aren't valid flags for wait4()
+ * directly (though they don't fail with EINVAL).
+ */
+ opt6 = options & (WEXITED | WTRAPPED);
+ options &= ~opt6;
+ printed = print_mask_int(fp, wait6opt, options, rem);
+ if (rem != NULL)
+ *rem |= opt6;
+ return (printed);
+}
+
+bool
+sysdecode_wait6_options(FILE *fp, int options, int *rem)
+{
+
+ return (print_mask_int(fp, wait6opt, options, rem));
+}
+
+const char *
+sysdecode_whence(int whence)
+{
+
+ return (lookup_value(seekwhence, whence));
+}
+
+const char *
+sysdecode_fcntl_cmd(int cmd)
+{
+
+ return (lookup_value(fcntlcmd, cmd));
+}
+
+static struct name_table fcntl_fd_arg[] = {
+ X(FD_CLOEXEC) X(FD_CLOFORK) X(0) XEND
+};
+
+bool
+sysdecode_fcntl_arg_p(int cmd)
+{
+
+ switch (cmd) {
+ case F_GETFD:
+ case F_GETFL:
+ case F_GETOWN:
+ return (false);
+ default:
+ return (true);
+ }
+}
+
+void
+sysdecode_fcntl_arg(FILE *fp, int cmd, uintptr_t arg, int base)
+{
+ int rem;
+
+ switch (cmd) {
+ case F_SETFD:
+ if (!print_value(fp, fcntl_fd_arg, arg))
+ print_integer(fp, arg, base);
+ break;
+ case F_SETFL:
+ if (!sysdecode_fcntl_fileflags(fp, arg, &rem))
+ fprintf(fp, "%#x", rem);
+ else if (rem != 0)
+ fprintf(fp, "|%#x", rem);
+ break;
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ fprintf(fp, "%p", (void *)arg);
+ break;
+ default:
+ print_integer(fp, arg, base);
+ break;
+ }
+}
+
+bool
+sysdecode_mmap_flags(FILE *fp, int flags, int *rem)
+{
+ uintmax_t val;
+ bool printed;
+ int align;
+
+ /*
+ * MAP_ALIGNED can't be handled directly by print_mask_int().
+ */
+ printed = false;
+ align = flags & MAP_ALIGNMENT_MASK;
+ val = (unsigned)flags & ~MAP_ALIGNMENT_MASK;
+ print_mask_part(fp, mmapflags, &val, &printed);
+ if (align != 0) {
+ if (printed)
+ fputc('|', fp);
+ if (align == MAP_ALIGNED_SUPER)
+ fputs("MAP_ALIGNED_SUPER", fp);
+ else
+ fprintf(fp, "MAP_ALIGNED(%d)",
+ align >> MAP_ALIGNMENT_SHIFT);
+ printed = true;
+ }
+ if (rem != NULL)
+ *rem = val;
+ return (printed);
+}
+
+const char *
+sysdecode_pathconf_name(int name)
+{
+
+ return (lookup_value(pathconfname, name));
+}
+
+const char *
+sysdecode_rtprio_function(int function)
+{
+
+ return (lookup_value(rtpriofuncs, function));
+}
+
+bool
+sysdecode_msg_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_0(fp, msgflags, flags, rem));
+}
+
+const char *
+sysdecode_sigcode(int sig, int si_code)
+{
+ const char *str;
+
+ str = lookup_value(sigcode, si_code);
+ if (str != NULL)
+ return (str);
+
+ switch (sig) {
+ case SIGILL:
+ return (sysdecode_sigill_code(si_code));
+ case SIGBUS:
+ return (sysdecode_sigbus_code(si_code));
+ case SIGSEGV:
+ return (sysdecode_sigsegv_code(si_code));
+ case SIGFPE:
+ return (sysdecode_sigfpe_code(si_code));
+ case SIGTRAP:
+ return (sysdecode_sigtrap_code(si_code));
+ case SIGCHLD:
+ return (sysdecode_sigchld_code(si_code));
+ default:
+ return (NULL);
+ }
+}
+
+const char *
+sysdecode_sysarch_number(int number)
+{
+
+ return (lookup_value(sysarchnum, number));
+}
+
+bool
+sysdecode_umtx_cvwait_flags(FILE *fp, u_long flags, u_long *rem)
+{
+
+ return (print_mask_0ul(fp, umtxcvwaitflags, flags, rem));
+}
+
+bool
+sysdecode_umtx_rwlock_flags(FILE *fp, u_long flags, u_long *rem)
+{
+
+ return (print_mask_0ul(fp, umtxrwlockflags, flags, rem));
+}
+
+void
+sysdecode_cap_rights(FILE *fp, cap_rights_t *rightsp)
+{
+ cap_rights_t diff, sum, zero;
+ const struct name_table *t;
+ int i;
+ bool comma;
+
+ for (i = 0; i < CAPARSIZE(rightsp); i++) {
+ if (CAPIDXBIT(rightsp->cr_rights[i]) != 1 << i) {
+ fprintf(fp, "invalid cap_rights_t");
+ return;
+ }
+ }
+ cap_rights_init(&sum);
+ diff = *rightsp;
+ for (t = caprights, comma = false; t->str != NULL; t++) {
+ if (cap_rights_is_set(rightsp, t->val)) {
+ cap_rights_clear(&diff, t->val);
+ if (cap_rights_is_set(&sum, t->val)) {
+ /* Don't print redundant rights. */
+ continue;
+ }
+ cap_rights_set(&sum, t->val);
+
+ fprintf(fp, "%s%s", comma ? "," : "", t->str);
+ comma = true;
+ }
+ }
+ if (!comma)
+ fprintf(fp, "CAP_NONE");
+
+ /*
+ * Provide a breadcrumb if some of the provided rights are not included
+ * in the table, likely due to a bug in the mktables script.
+ */
+ CAP_NONE(&zero);
+ if (!cap_rights_contains(&zero, &diff))
+ fprintf(fp, ",unknown rights");
+}
+
+/*
+ * Pre-sort the set of rights, which has a partial ordering defined by the
+ * subset relation. This lets sysdecode_cap_rights() print a list of minimal
+ * length with a single pass over the "caprights" table.
+ */
+static void __attribute__((constructor))
+sysdecode_cap_rights_init(void)
+{
+ cap_rights_t tr, qr;
+ struct name_table *t, *q, tmp;
+ bool swapped;
+
+ do {
+ for (t = caprights, swapped = false; t->str != NULL; t++) {
+ cap_rights_init(&tr, t->val);
+ for (q = t + 1; q->str != NULL; q++) {
+ cap_rights_init(&qr, q->val);
+ if (cap_rights_contains(&qr, &tr)) {
+ tmp = *t;
+ *t = *q;
+ *q = tmp;
+ swapped = true;
+ }
+ }
+ }
+ } while (swapped);
+}
+
+static struct name_table cmsgtypeip[] = {
+ X(IP_RECVDSTADDR) X(IP_RECVTTL) X(IP_RECVOPTS) X(IP_RECVRETOPTS)
+ X(IP_RECVIF) X(IP_RECVTOS) X(IP_FLOWID) X(IP_FLOWTYPE)
+ X(IP_RSSBUCKETID) XEND
+};
+
+static struct name_table cmsgtypeipv6[] = {
+#if 0
+ /* The RFC 2292 defines are kernel space only. */
+ X(IPV6_2292PKTINFO) X(IPV6_2292HOPLIMIT) X(IPV6_2292HOPOPTS)
+ X(IPV6_2292DSTOPTS) X(IPV6_2292RTHDR) X(IPV6_2292NEXTHOP)
+#endif
+ X(IPV6_PKTINFO) X(IPV6_HOPLIMIT) X(IPV6_HOPOPTS)
+ X(IPV6_DSTOPTS) X(IPV6_RTHDR) X(IPV6_NEXTHOP)
+ X(IPV6_TCLASS) X(IPV6_FLOWID) X(IPV6_FLOWTYPE) X(IPV6_RSSBUCKETID)
+ X(IPV6_PATHMTU) X(IPV6_RTHDRDSTOPTS) X(IPV6_USE_MIN_MTU)
+ X(IPV6_DONTFRAG) X(IPV6_PREFER_TEMPADDR) XEND
+};
+
+static struct name_table cmsgtypesctp[] = {
+ X(SCTP_INIT) X(SCTP_SNDRCV) X(SCTP_EXTRCV) X(SCTP_SNDINFO)
+ X(SCTP_RCVINFO) X(SCTP_NXTINFO) X(SCTP_PRINFO) X(SCTP_AUTHINFO)
+ X(SCTP_DSTADDRV4) X(SCTP_DSTADDRV6) XEND
+};
+
+const char *
+sysdecode_cmsg_type(int cmsg_level, int cmsg_type)
+{
+
+ if (cmsg_level == SOL_SOCKET)
+ return (lookup_value(cmsgtypesocket, cmsg_type));
+ if (cmsg_level == IPPROTO_IP)
+ return (lookup_value(cmsgtypeip, cmsg_type));
+ if (cmsg_level == IPPROTO_IPV6)
+ return (lookup_value(cmsgtypeipv6, cmsg_type));
+ if (cmsg_level == IPPROTO_SCTP)
+ return (lookup_value(cmsgtypesctp, cmsg_type));
+ return (NULL);
+}
+
+const char *
+sysdecode_sctp_pr_policy(int policy)
+{
+
+ return (lookup_value(sctpprpolicy, policy));
+}
+
+static struct name_table sctpsndflags[] = {
+ X(SCTP_EOF) X(SCTP_ABORT) X(SCTP_UNORDERED) X(SCTP_ADDR_OVER)
+ X(SCTP_SENDALL) X(SCTP_EOR) X(SCTP_SACK_IMMEDIATELY) XEND
+};
+
+bool
+sysdecode_sctp_snd_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, sctpsndflags, flags, rem));
+}
+
+static struct name_table sctprcvflags[] = {
+ X(SCTP_UNORDERED) XEND
+};
+
+bool
+sysdecode_sctp_rcv_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, sctprcvflags, flags, rem));
+}
+
+static struct name_table sctpnxtflags[] = {
+ X(SCTP_UNORDERED) X(SCTP_COMPLETE) X(SCTP_NOTIFICATION) XEND
+};
+
+bool
+sysdecode_sctp_nxt_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, sctpnxtflags, flags, rem));
+}
+
+static struct name_table sctpsinfoflags[] = {
+ X(SCTP_EOF) X(SCTP_ABORT) X(SCTP_UNORDERED) X(SCTP_ADDR_OVER)
+ X(SCTP_SENDALL) X(SCTP_EOR) X(SCTP_SACK_IMMEDIATELY) XEND
+};
+
+void
+sysdecode_sctp_sinfo_flags(FILE *fp, int sinfo_flags)
+{
+ const char *temp;
+ int rem;
+ bool printed;
+
+ printed = print_mask_0(fp, sctpsinfoflags, sinfo_flags, &rem);
+ if (rem & ~SCTP_PR_SCTP_ALL) {
+ fprintf(fp, "%s%#x", printed ? "|" : "", rem & ~SCTP_PR_SCTP_ALL);
+ printed = true;
+ rem &= ~SCTP_PR_SCTP_ALL;
+ }
+ if (rem != 0) {
+ temp = sysdecode_sctp_pr_policy(rem);
+ if (temp != NULL) {
+ fprintf(fp, "%s%s", printed ? "|" : "", temp);
+ } else {
+ fprintf(fp, "%s%#x", printed ? "|" : "", rem);
+ }
+ }
+}
+
+bool
+sysdecode_shmflags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_0(fp, shmflags, flags, rem));
+}
+
+const char *
+sysdecode_itimer(int which)
+{
+
+ return (lookup_value(itimerwhich, which));
+}
diff --git a/lib/libsysdecode/linux.c b/lib/libsysdecode/linux.c
new file mode 100644
index 000000000000..1ad3b4f89806
--- /dev/null
+++ b/lib/libsysdecode/linux.c
@@ -0,0 +1,253 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Dmitry Chagin <dchagin@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sysdecode.h>
+
+#include "support.h"
+
+#ifdef __aarch64__
+#include <arm64/linux/linux.h>
+#elif __i386__
+#include <i386/linux/linux.h>
+#elif __amd64__
+#include <amd64/linux/linux.h>
+#else
+#error "Unsupported Linux arch"
+#endif
+
+#include <compat/linux/linux.h>
+#include <compat/linux/linux_file.h>
+#include <compat/linux/linux_fork.h>
+#include <compat/linux/linux_time.h>
+
+#define X(a,b) { a, #b },
+#define XEND { 0, NULL }
+
+#define TABLE_START(n) static struct name_table n[] = {
+#define TABLE_ENTRY X
+#define TABLE_END XEND };
+
+#include "tables_linux.h"
+
+#undef TABLE_START
+#undef TABLE_ENTRY
+#undef TABLE_END
+
+static const char *linux_signames[] = {
+ [LINUX_SIGHUP] = "SIGHUP",
+ [LINUX_SIGINT] = "SIGINT",
+ [LINUX_SIGQUIT] = "SIGQUIT",
+ [LINUX_SIGILL] = "SIGILL",
+ [LINUX_SIGTRAP] = "SIGTRAP",
+ [LINUX_SIGABRT] = "SIGABRT",
+ [LINUX_SIGBUS] = "SIGBUS",
+ [LINUX_SIGFPE] = "SIGFPE",
+ [LINUX_SIGKILL] = "SIGKILL",
+ [LINUX_SIGUSR1] = "SIGUSR1",
+ [LINUX_SIGSEGV] = "SIGSEGV",
+ [LINUX_SIGUSR2] = "SIGUSR2",
+ [LINUX_SIGPIPE] = "SIGPIPE",
+ [LINUX_SIGALRM] = "SIGALRM",
+ [LINUX_SIGTERM] = "SIGTERM",
+ [LINUX_SIGSTKFLT] = "SIGSTKFLT",
+ [LINUX_SIGCHLD] = "SIGCHLD",
+ [LINUX_SIGCONT] = "SIGCONT",
+ [LINUX_SIGSTOP] = "SIGSTOP",
+ [LINUX_SIGTSTP] = "SIGTSTP",
+ [LINUX_SIGTTIN] = "SIGTTIN",
+ [LINUX_SIGTTOU] = "SIGTTOU",
+ [LINUX_SIGURG] = "SIGURG",
+ [LINUX_SIGXCPU] = "SIGXCPU",
+ [LINUX_SIGXFSZ] = "SIGXFSZ",
+ [LINUX_SIGVTALRM] = "SIGVTALRM",
+ [LINUX_SIGPROF] = "SIGPROF",
+ [LINUX_SIGWINCH] = "SIGWINCH",
+ [LINUX_SIGIO] = "SIGIO",
+ [LINUX_SIGPWR] = "SIGPWR",
+ [LINUX_SIGSYS] = "SIGSYS",
+
+ [LINUX_SIGRTMIN] = "SIGCANCEL",
+ [LINUX_SIGRTMIN + 1] = "SIGSETXID",
+ [LINUX_SIGRTMIN + 2] = "SIGRT2",
+ [LINUX_SIGRTMIN + 3] = "SIGRT3",
+ [LINUX_SIGRTMIN + 4] = "SIGRT4",
+ [LINUX_SIGRTMIN + 5] = "SIGRT5",
+ [LINUX_SIGRTMIN + 6] = "SIGRT6",
+ [LINUX_SIGRTMIN + 7] = "SIGRT7",
+ [LINUX_SIGRTMIN + 8] = "SIGRT8",
+ [LINUX_SIGRTMIN + 9] = "SIGRT9",
+ [LINUX_SIGRTMIN + 10] = "SIGRT10",
+ [LINUX_SIGRTMIN + 11] = "SIGRT11",
+ [LINUX_SIGRTMIN + 12] = "SIGRT12",
+ [LINUX_SIGRTMIN + 13] = "SIGRT13",
+ [LINUX_SIGRTMIN + 14] = "SIGRT14",
+ [LINUX_SIGRTMIN + 15] = "SIGRT15",
+ [LINUX_SIGRTMIN + 16] = "SIGRT16",
+ [LINUX_SIGRTMIN + 17] = "SIGRT17",
+ [LINUX_SIGRTMIN + 18] = "SIGRT18",
+ [LINUX_SIGRTMIN + 19] = "SIGRT19",
+ [LINUX_SIGRTMIN + 20] = "SIGRT20",
+ [LINUX_SIGRTMIN + 21] = "SIGRT21",
+ [LINUX_SIGRTMIN + 22] = "SIGRT22",
+ [LINUX_SIGRTMIN + 23] = "SIGRT23",
+ [LINUX_SIGRTMIN + 24] = "SIGRT24",
+ [LINUX_SIGRTMIN + 25] = "SIGRT25",
+ [LINUX_SIGRTMIN + 26] = "SIGRT26",
+ [LINUX_SIGRTMIN + 27] = "SIGRT27",
+ [LINUX_SIGRTMIN + 28] = "SIGRT28",
+ [LINUX_SIGRTMIN + 29] = "SIGRT29",
+ [LINUX_SIGRTMIN + 30] = "SIGRT30",
+ [LINUX_SIGRTMIN + 31] = "SIGRT31",
+ [LINUX_SIGRTMIN + 32] = "SIGRTMAX",
+};
+_Static_assert(nitems(linux_signames) == LINUX_SIGRTMAX + 1,
+ "invalid entries count in linux_signames");
+
+void
+sysdecode_linux_clockid(FILE *fp, clockid_t which)
+{
+ const char *str;
+ clockid_t ci;
+ pid_t pid;
+
+ if (which >= 0) {
+ str = lookup_value(clockids, which);
+ if (str == NULL)
+ fprintf(fp, "UNKNOWN(%d)", which);
+ else
+ fputs(str, fp);
+ return;
+ }
+ if ((which & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD_MASK) {
+ fputs("INVALID PERTHREAD|CLOCKFD", fp);
+ goto pidp;
+ }
+ ci = LINUX_CPUCLOCK_WHICH(which);
+ if (LINUX_CPUCLOCK_PERTHREAD(which) == true)
+ fputs("THREAD|", fp);
+ else
+ fputs("PROCESS|", fp);
+ str = lookup_value(clockcpuids, ci);
+ if (str != NULL)
+ fputs(str, fp);
+ else {
+ if (ci == LINUX_CLOCKFD)
+ fputs("CLOCKFD", fp);
+ else
+ fprintf(fp, "UNKNOWN(%d)", which);
+ }
+
+pidp:
+ pid = LINUX_CPUCLOCK_ID(which);
+ fprintf(fp, "(%d)", pid);
+}
+
+const char *
+sysdecode_linux_signal(int sig)
+{
+
+ if ((unsigned)sig < nitems(linux_signames))
+ return (linux_signames[sig]);
+ return (NULL);
+}
+
+const char *
+sysdecode_linux_sigprocmask_how(int how)
+{
+
+ return (lookup_value(sigprocmaskhow, how));
+}
+
+bool
+sysdecode_linux_clock_flags(FILE *fp, int flags, int *rem)
+{
+
+ return (print_mask_int(fp, clockflags, flags, rem));
+}
+
+bool
+sysdecode_linux_atflags(FILE *fp, int flag, int *rem)
+{
+
+ return (print_mask_int(fp, atflags, flag, rem));
+}
+
+bool
+sysdecode_linux_open_flags(FILE *fp, int flags, int *rem)
+{
+ bool printed;
+ int mode;
+ uintmax_t val;
+
+ mode = flags & LINUX_O_ACCMODE;
+ flags &= ~LINUX_O_ACCMODE;
+ switch (mode) {
+ case LINUX_O_RDONLY:
+ fputs("O_RDONLY", fp);
+ printed = true;
+ mode = 0;
+ break;
+ case LINUX_O_WRONLY:
+ fputs("O_WRONLY", fp);
+ printed = true;
+ mode = 0;
+ break;
+ case LINUX_O_RDWR:
+ fputs("O_RDWR", fp);
+ printed = true;
+ mode = 0;
+ break;
+ default:
+ printed = false;
+ }
+ val = (unsigned)flags;
+ print_mask_part(fp, openflags, &val, &printed);
+ if (rem != NULL)
+ *rem = val | mode;
+ return (printed);
+}
+
+bool
+sysdecode_linux_clone_flags(FILE *fp, int flags, int *rem)
+{
+ uintmax_t val;
+ bool printed;
+ int sig;
+
+ sig = flags & LINUX_CSIGNAL;
+ if (sig != 0)
+ fprintf(fp, "(%s)", sysdecode_linux_signal(sig));
+ val = (unsigned)flags & ~LINUX_CSIGNAL;
+ print_mask_part(fp, cloneflags, &val, &printed);
+ if (rem != NULL)
+ *rem = val;
+ return (printed);
+}
diff --git a/lib/libsysdecode/mkioctls b/lib/libsysdecode/mkioctls
new file mode 100644
index 000000000000..e48001e1f6a5
--- /dev/null
+++ b/lib/libsysdecode/mkioctls
@@ -0,0 +1,106 @@
+#!/bin/sh
+#
+
+set -e
+
+if [ $# -ne 1 ]; then
+ echo "usage: sh $0 include-dir"
+ exit 1
+fi
+
+includedir="$1"
+
+LC_ALL=C; export LC_ALL
+
+# Build a list of headers that have ioctls in them.
+# XXX should we use an ANSI cpp?
+ioctl_includes=$(
+ cd $includedir
+ set -e
+ # if /bin/sh is bash this will avoid further errors due to missing commands
+ if set -o | grep -q pipefail; then
+ set -o pipefail
+ fi
+
+ filter='tee'
+ if [ "${MK_PF}" = "no" ]; then
+ filter='egrep -v (net/pfvar|net/if_pfsync)\.h'
+ fi
+ # find -s would avoid the need to invoke sort but it is non-portable
+ find -L ./* -type f -name '*.h' | \
+ LC_ALL=C sort | \
+ $filter | \
+ xargs egrep -l \
+'^#[ ]*define[ ]+[A-Za-z_][A-Za-z0-9_]*[ ]+_IO[^a-z0-9_]' |
+ awk '{printf("#include <%s>\\n", $1)}'
+)
+
+if [ -z "$ioctl_includes" ]; then
+ echo "Failed to build list of ioctl headers"
+ exit 1
+fi
+
+awk -v x="$ioctl_includes" 'BEGIN {print x}' |
+ $CPP -nostdinc -I$includedir -dM -DCOMPAT_43TTY - |
+ awk -v ioctl_includes="$ioctl_includes" '
+BEGIN {
+ print "/* XXX obnoxious prerequisites. */"
+ print "#define COMPAT_43"
+ print "#define COMPAT_43TTY"
+ print "#include <sys/param.h>"
+ print "#include <sys/devicestat.h>"
+ print "#include <sys/disklabel.h>"
+ print "#include <sys/mman.h>"
+ print "#include <sys/socket.h>"
+ print "#include <sys/time.h>"
+ print "#include <sys/tty.h>"
+ print "#include <bsm/audit.h>"
+ print "#include <net/ethernet.h>"
+ print "#include <net/if.h>"
+ print "#ifdef PF"
+ print "#include <net/pfvar.h>"
+ print "#include <net/if_pfsync.h>"
+ print "#endif"
+ print "#include <net/route.h>"
+ print "#include <netinet/in.h>"
+ print "#include <netinet/ip_mroute.h>"
+ print "#include <netinet6/in6_var.h>"
+ print "#include <netinet6/nd6.h>"
+ print "#include <netinet6/ip6_mroute.h>"
+ print "#include <stdio.h>"
+ print "#include <cam/cam.h>"
+ print "#include <cam/scsi/scsi_pass.h>"
+ print "#include <stdbool.h>"
+ print "#include <stddef.h>"
+ print "#include <stdint.h>"
+ print "#include <sysdecode.h>"
+ print ""
+ print ioctl_includes
+ print ""
+ print "const char *"
+ print "sysdecode_ioctlname(unsigned long val)"
+ print "{"
+ print "\tconst char *str = NULL;"
+ print ""
+}
+
+/^#[ ]*define[ ]+[A-Za-z_][A-Za-z0-9_]*[ ]+_IO/ {
+
+ # find where the name starts
+ for (i = 1; i <= NF; i++)
+ if ($i ~ /define/)
+ break;
+ ++i;
+ #
+ printf("\t");
+ if (n++ > 0)
+ printf("else ");
+ printf("if (val == %s)\n", $i);
+ printf("\t\tstr = \"%s\";\n", $i);
+}
+END {
+ print ""
+ print "\treturn (str);"
+ print "}"
+}
+'
diff --git a/lib/libsysdecode/mklinuxtables b/lib/libsysdecode/mklinuxtables
new file mode 100644
index 000000000000..abcdeb9440b6
--- /dev/null
+++ b/lib/libsysdecode/mklinuxtables
@@ -0,0 +1,113 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#
+# Generates tables_linux.h
+#
+
+set -e
+
+LC_ALL=C; export LC_ALL
+
+if [ -z "$1" ]
+then
+ echo "usage: sh $0 include-dir [output-file]"
+ exit 1
+fi
+include_dir=$1
+if [ -n "$2" ]; then
+ output_file="$2"
+ output_tmp=$(mktemp -u)
+ exec > "$output_tmp"
+fi
+
+all_headers=
+#
+# Generate a table C #definitions. The including file can define the
+# TABLE_NAME(n), TABLE_ENTRY(x), and TABLE_END macros to define what
+# the tables map to.
+#
+gen_table()
+{
+ local name grep file excl filter
+ name=$1
+ grep=$2
+ file=$3
+ excl=$4
+
+ if [ -z "$excl" ]; then
+ filter="cat"
+ else
+ filter="egrep -v"
+ fi
+ cat <<_EOF_
+TABLE_START(${name})
+_EOF_
+ if [ -e "${include_dir}/${file}" ]; then
+ all_headers="${all_headers:+${all_headers} }${file}"
+ egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
+ $include_dir/$file | ${filter} ${excl} | \
+ awk '{ for (i = 1; i <= NF; i++) \
+ if ($i ~ /define/) \
+ break; \
+ ++i; \
+ sub(/LINUX_/, "", $i); \
+ printf "TABLE_ENTRY(LINUX_%s, %s)\n", $i, $i }'
+ fi
+cat <<_EOF_
+TABLE_END
+
+_EOF_
+}
+
+cat <<_EOF_
+/* This file is auto-generated. */
+
+_EOF_
+
+gen_table "atflags" "LINUX_AT_[A-Z_]+[[:space:]]+[0-9]+" "compat/linux/linux_file.h"
+gen_table "clockids" "LINUX_CLOCK_[A-Z_]+[[:space:]]+[0-9]+" "compat/linux/linux_time.h"
+gen_table "clockflags" "LINUX_TIMER_[A-Z_]+[[:space:]]+0x[0-9]+" "compat/linux/linux_time.h"
+gen_table "clockcpuids" "LINUX_CPUCLOCK_[A-Z_]+[[:space:]]+[0-9]+" "compat/linux/linux_time.h" "_MASK|_MAX"
+gen_table "openflags" "LINUX_O_[A-Z_]+[[:space:]]+[0-9]+" "compat/linux/linux_file.h" "O_RDONLY|O_RDWR|O_WRONLY|O_ACCMODE"
+gen_table "sigprocmaskhow" "LINUX_SIG_[A-Z]+[[:space:]]+[0-9]+" "compat/linux/linux.h"
+gen_table "cloneflags" "LINUX_CLONE_[A-Z_]+[[:space:]]+[[:alnum:]]+" "compat/linux/linux_fork.h" "LINUX_CLONE_LEGACY_FLAGS|LINUX_CLONE_CLEAR_SIGHAND|LINUX_CLONE_INTO_CGROUP|LINUX_CLONE_NEWTIME"
+
+# Generate a .depend file for our output file
+if [ -n "$output_file" ]; then
+ depend_tmp=$(mktemp -u)
+ {
+ echo "$output_file: \\"
+ echo "$all_headers" | tr ' ' '\n' | sort -u |
+ sed -e "s,^, $include_dir/," -e 's,$, \\,'
+ echo
+ } > "$depend_tmp"
+ if cmp -s "$output_tmp" "$output_file"; then
+ rm -f "$output_tmp" "$depend_tmp"
+ else
+ mv -f "$depend_tmp" ".depend.${output_file}"
+ mv -f "$output_tmp" "$output_file"
+ fi
+fi
diff --git a/lib/libsysdecode/mktables b/lib/libsysdecode/mktables
new file mode 100644
index 000000000000..6b4f79402660
--- /dev/null
+++ b/lib/libsysdecode/mktables
@@ -0,0 +1,189 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#
+# Generates tables.h
+#
+# Originally this script was 'mksubr' for kdump which generated a complete
+# C file along with function definitions. Now this script generates tables
+# of constants and names extracted from header files.
+
+set -e
+
+LC_ALL=C; export LC_ALL
+
+if [ -z "$1" ]
+then
+ echo "usage: sh $0 include-dir [output-file]"
+ exit 1
+fi
+include_dir=$1
+if [ -n "$2" ]; then
+ output_file="$2"
+ output_tmp=$(mktemp -u)
+ exec > "$output_tmp"
+fi
+
+all_headers=
+#
+# Generate a table C #definitions. The including file can define the
+# TABLE_NAME(n), TABLE_ENTRY(x), and TABLE_END macros to define what
+# the tables map to.
+#
+gen_table()
+{
+ local name grep file excl filter
+ name=$1
+ grep=$2
+ file=$3
+ excl=$4
+
+ if [ -z "$excl" ]; then
+ filter="cat"
+ else
+ filter="egrep -v"
+ fi
+ cat <<_EOF_
+TABLE_START(${name})
+_EOF_
+ if [ -e "${include_dir}/${file}" ]; then
+ all_headers="${all_headers:+${all_headers} }${file}"
+ egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
+ $include_dir/$file | ${filter} ${excl} | \
+ awk '{ for (i = 1; i <= NF; i++) \
+ if ($i ~ /define/) \
+ break; \
+ ++i; \
+ printf "TABLE_ENTRY(%s)\n", $i }'
+ fi
+cat <<_EOF_
+TABLE_END
+
+_EOF_
+}
+
+cat <<_EOF_
+/* This file is auto-generated. */
+
+_EOF_
+
+gen_table "accessmode" "[A-Z]_OK[[:space:]]+0?x?[0-9A-Fa-f]+" "sys/unistd.h"
+gen_table "acltype" "ACL_TYPE_[A-Z4_]+[[:space:]]+0x[0-9]+" "sys/acl.h"
+gen_table "atflags" "AT_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/fcntl.h"
+gen_table "capfcntl" "CAP_FCNTL_[A-Z]+[[:space:]]+\(1" "sys/capsicum.h"
+gen_table "closerangeflags" "CLOSE_RANGE_[A-Z]+[[:space:]]+\([0-9]+<<[0-9]+\)" "sys/unistd.h"
+gen_table "extattrns" "EXTATTR_NAMESPACE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/extattr.h"
+gen_table "fadvisebehav" "POSIX_FADV_[A-Z]+[[:space:]]+[0-9]+" "sys/fcntl.h"
+gen_table "openflags" "O_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/fcntl.h" "O_RDONLY|O_RDWR|O_WRONLY"
+gen_table "flockops" "LOCK_[A-Z]+[[:space:]]+0x[0-9]+" "sys/fcntl.h"
+gen_table "inotifyflags" "IN_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/inotify.h" "IN_CLOEXEC|IN_NONBLOCK"
+gen_table "kldsymcmd" "KLDSYM_[A-Z]+[[:space:]]+[0-9]+" "sys/linker.h"
+gen_table "kldunloadfflags" "LINKER_UNLOAD_[A-Z]+[[:space:]]+[0-9]+" "sys/linker.h"
+gen_table "lio_listiomodes" "LIO_(NO)?WAIT[[:space:]]+[0-9]+" "aio.h"
+gen_table "madvisebehav" "_?MADV_[A-Z]+[[:space:]]+[0-9]+" "sys/mman.h"
+gen_table "minheritflags" "INHERIT_[A-Z]+[[:space:]]+[0-9]+" "sys/mman.h"
+gen_table "mlockallflags" "MCL_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mman.h"
+gen_table "mmapprot" "PROT_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/mman.h"
+gen_table "ngbtsolevel" "SOL_[A-Z0-9]+[[:space:]]+0x[0-9A-Fa-f]+" "netgraph/bluetooth/include/ng_btsocket.h"
+gen_table "fileflags" "[SU]F_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/stat.h" "UF_COMPRESSED|UF_TRACKED|UF_SETTABLE|SF_SETTABLE"
+gen_table "filemode" "S_[A-Z]+[[:space:]]+[0-6]{7}" "sys/stat.h"
+gen_table "keventflags" "EV_[A-Z]+[[:space:]]+0x[0-9]+" "sys/event.h" "EV_SYSFLAGS|EV_DROP|EV_FLAG[12]"
+gen_table "keventfilters" "EVFILT_[A-Z]+[[:space:]]+\(-[0-9]+\)" "sys/event.h"
+gen_table "mountflags" "MNT_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mount.h"
+gen_table "msyncflags" "MS_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mman.h"
+gen_table "nfssvcflags" "NFSSVC_[A-Z0-9]+[[:space:]]+0x[0-9]+" "nfs/nfssvc.h"
+gen_table "pathconfname" "_PC_[A-Z4_]+[[:space:]]+[0-9]+" "sys/unistd.h"
+gen_table "pollfdevents" "POLL[A-Z]+[[:space:]]+" "sys/poll.h"
+gen_table "prio" "PRIO_[A-Z]+[[:space:]]+[0-9]" "sys/resource.h"
+gen_table "procctlcmd" "PROC_[A-Z_]+[[:space:]]+[0-9]" "sys/procctl.h" "PROC_TRACE_CTL_"
+gen_table "ptraceop" "PT_[[:alnum:]_]+[[:space:]]+[0-9]+" "sys/ptrace.h"
+gen_table "quotactlcmds" "Q_[A-Z]+[[:space:]]+0x[0-9]+" "ufs/ufs/quota.h"
+gen_table "rebootopt" "RB_[A-Z]+[[:space:]]+0x[0-9]+" "sys/reboot.h"
+gen_table "rforkflags" "RF[A-Z]+[[:space:]]+\([0-9]+[uU]?<<[0-9]+\)" "sys/unistd.h" "RFPPWAIT"
+gen_table "rlimit" "RLIMIT_[A-Z]+[[:space:]]+[0-9]+" "sys/resource.h"
+gen_table "rusage" "RUSAGE_[A-Z]+[[:space:]]+[-0-9]+" "sys/resource.h"
+gen_table "schedpolicy" "SCHED_[A-Z]+[[:space:]]+[0-9]+" "sys/sched.h"
+gen_table "sendfileflags" "SF_[A-Z]+[[:space:]]+[0-9]+" "sys/socket.h"
+gen_table "shmatflags" "SHM_[A-Z]+[[:space:]]+[0-9]{6}" "sys/shm.h"
+gen_table "shutdownhow" "SHUT_[A-Z]+[[:space:]]+[0-9]+" "sys/socket.h"
+gen_table "sigbuscode" "BUS_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+gen_table "sigchldcode" "CLD_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+gen_table "sigfpecode" "FPE_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+gen_table "sigprocmaskhow" "SIG_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+gen_table "sigillcode" "ILL_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+gen_table "sigsegvcode" "SEGV_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+gen_table "sigtrapcode" "TRAP_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+gen_table "sockdomain" "PF_[[:alnum:]]+[[:space:]]+" "sys/socket.h"
+gen_table "sockfamily" "AF_[[:alnum:]]+[[:space:]]+" "sys/socket.h"
+gen_table "sockipproto" "IPPROTO_[[:alnum:]]+[[:space:]]+" "netinet/in.h"
+gen_table "sockopt" "SO_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/socket.h"
+gen_table "sockoptip" "(IP_[[:alnum:]_]+|MCAST_[[:alnum:]_]+_GROUP)[[:space:]]+" "netinet/in.h" "IP_DEFAULT|IP_MIN|IP_MAX|IP_PORTRANGE"
+gen_table "sockoptipv6" "IPV6_[[:alnum:]_]+[[:space:]]+[0-9]+" "netinet6/in6.h" "IPV6_ADDR_|IPV6_TAG_DIRECT|IPV6_OPTIONS|IPV6_RECVOPTS|IPV6_RECVRETOPTS|IPV6_RECVDSTADDR|IPV6_RETOPTS|IPV6_2292|IPV6_RECVRTHDRDSTOPTS|IPV6_REACHCONF|IPV6_PKTOPTIONS"
+gen_table "sockoptsctp" "SCTP_[[:alnum:]_]+[[:space:]]+[0-9]+" "netinet/sctp.h"
+gen_table "sockopttcp" "TCP_[[:alnum:]_]+[[:space:]]+[0-9]+" "netinet/tcp.h" "TCP_MIN|TCP_MAX[^S]|TCP_MSS|TCP_[[:alnum:]_]+_MAX|TCP_FASTOPEN_MIN_COOKIE_LEN|TCP_FASTOPEN_PSK_LEN|TCP_USE_DDP"
+gen_table "sockoptudp" "UDP_[[:alnum:]]+[[:space:]]+[0-9]+" "netinet/udp.h" "UDP_ENCAP_"
+gen_table "sockoptudplite" "UDPLITE_[[:alnum:]_]+[[:space:]]+[0-9]+" "netinet/udplite.h"
+gen_table "socktype" "SOCK_[A-Z]+[[:space:]]+[1-9]+[0-9]*" "sys/socket.h"
+gen_table "thrcreateflags" "THR_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/thr.h"
+gen_table "umtxop" "UMTX_OP_[[:alnum:]][[:alnum:]_]*[[:space:]]+[0-9]+" "sys/umtx.h"
+gen_table "umtxopflags" "UMTX_OP__[[:alnum:]_]+[[:space:]]+[0-9]+" "sys/umtx.h"
+gen_table "vmprot" "VM_PROT_[A-Z_]+[[:space:]]+\(\(vm_prot_t\)[[:space:]]+0x[0-9]+\)" "vm/vm.h"
+gen_table "vmresult" "KERN_[A-Z_]+[[:space:]]+[0-9]+" "vm/vm_param.h"
+gen_table "wait6opt" "W[A-Z]+[[:space:]]+[0-9]+" "sys/wait.h"
+gen_table "seekwhence" "SEEK_[A-Z]+[[:space:]]+[0-9]+" "sys/unistd.h"
+gen_table "fcntlcmd" "F_[A-Z0-9_]+[[:space:]]+[0-9]+[[:space:]]+" "sys/fcntl.h" "F_CANCEL|F_..LCK"
+gen_table "mmapflags" "MAP_[2-3A-Z_]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/mman.h"
+gen_table "rtpriofuncs" "RTP_[A-Z]+[[:space:]]+[0-9]+" "sys/rtprio.h"
+gen_table "msgflags" "MSG_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/socket.h" "MSG_SOCALLBCK|MSG_MORETOCOME|MSG_TLSAPPDATA"
+gen_table "sigcode" "SI_[A-Z]+[[:space:]]+0(x[0-9abcdef]+)?" "sys/signal.h"
+gen_table "umtxcvwaitflags" "CVWAIT_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/umtx.h"
+gen_table "umtxrwlockflags" "URWLOCK_PREFER_READER[[:space:]]+0x[0-9]+" "sys/umtx.h"
+gen_table "caprights" "CAP_[A-Z_]+[[:space:]]+((CAPRIGHT\([0-9],[[:space:]]+0x[0-9]{16}ULL\))|(\(CAP_[A-Z_]+[[:space:]]*\|.*\)))" "sys/capsicum.h"
+gen_table "sctpprpolicy" "SCTP_PR_SCTP_[A-Z_]+[[:space:]]+0x[0-9]+" "netinet/sctp_uio.h" "SCTP_PR_SCTP_ALL"
+gen_table "cmsgtypesocket" "SCM_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/socket.h"
+if [ -e "${include_dir}/x86/sysarch.h" ]; then
+ gen_table "sysarchnum" "(AMD64|I386)_[A-Z86_]+[[:space:]]+[0-9]+" "x86/sysarch.h"
+else
+ gen_table "sysarchnum" "[A-Z_]+[[:space:]]+[0-9]+" "machine/sysarch.h"
+fi
+gen_table "shmflags" "SHM_[A-Z_]+[[:space:]]+0x[0-9]+" "sys/mman.h" "SHM_ANON"
+gen_table "itimerwhich" "ITIMER_[A-Z]+[[:space:]]+[0-9]+" "sys/time.h"
+
+# Generate a .depend file for our output file
+if [ -n "$output_file" ]; then
+ depend_tmp=$(mktemp -u)
+ {
+ echo "$output_file: \\"
+ echo "$all_headers" | tr ' ' '\n' | sort -u |
+ sed -e "s,^, $include_dir/," -e 's,$, \\,'
+ echo
+ } > "$depend_tmp"
+ if cmp -s "$output_tmp" "$output_file"; then
+ rm -f "$output_tmp" "$depend_tmp"
+ else
+ mv -f "$depend_tmp" ".depend.${output_file}"
+ mv -f "$output_tmp" "$output_file"
+ fi
+fi
diff --git a/lib/libsysdecode/signal.c b/lib/libsysdecode/signal.c
new file mode 100644
index 000000000000..29666eef3086
--- /dev/null
+++ b/lib/libsysdecode/signal.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2016 John H. Baldwin <jhb@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sysdecode.h>
+
+static const char *signames[] = {
+ [SIGHUP] = "SIGHUP",
+ [SIGINT] = "SIGINT",
+ [SIGQUIT] = "SIGQUIT",
+ [SIGILL] = "SIGILL",
+ [SIGTRAP] = "SIGTRAP",
+ [SIGABRT] = "SIGABRT",
+ [SIGEMT] = "SIGEMT",
+ [SIGFPE] = "SIGFPE",
+ [SIGKILL] = "SIGKILL",
+ [SIGBUS] = "SIGBUS",
+ [SIGSEGV] = "SIGSEGV",
+ [SIGSYS] = "SIGSYS",
+ [SIGPIPE] = "SIGPIPE",
+ [SIGALRM] = "SIGALRM",
+ [SIGTERM] = "SIGTERM",
+ [SIGURG] = "SIGURG",
+ [SIGSTOP] = "SIGSTOP",
+ [SIGTSTP] = "SIGTSTP",
+ [SIGCONT] = "SIGCONT",
+ [SIGCHLD] = "SIGCHLD",
+ [SIGTTIN] = "SIGTTIN",
+ [SIGTTOU] = "SIGTTOU",
+ [SIGIO] = "SIGIO",
+ [SIGXCPU] = "SIGXCPU",
+ [SIGXFSZ] = "SIGXFSZ",
+ [SIGVTALRM] = "SIGVTALRM",
+ [SIGPROF] = "SIGPROF",
+ [SIGWINCH] = "SIGWINCH",
+ [SIGINFO] = "SIGINFO",
+ [SIGUSR1] = "SIGUSR1",
+ [SIGUSR2] = "SIGUSR2",
+ [SIGTHR] = "SIGTHR",
+ [SIGLIBRT] = "SIGLIBRT",
+
+ /* XXX: Solaris uses SIGRTMIN, SIGRTMIN+<x>...SIGRTMAX-<x>, SIGRTMAX */
+ [SIGRTMIN] = "SIGRT0",
+ [SIGRTMIN + 1] = "SIGRT1",
+ [SIGRTMIN + 2] = "SIGRT2",
+ [SIGRTMIN + 3] = "SIGRT3",
+ [SIGRTMIN + 4] = "SIGRT4",
+ [SIGRTMIN + 5] = "SIGRT5",
+ [SIGRTMIN + 6] = "SIGRT6",
+ [SIGRTMIN + 7] = "SIGRT7",
+ [SIGRTMIN + 8] = "SIGRT8",
+ [SIGRTMIN + 9] = "SIGRT9",
+ [SIGRTMIN + 10] = "SIGRT10",
+ [SIGRTMIN + 11] = "SIGRT11",
+ [SIGRTMIN + 12] = "SIGRT12",
+ [SIGRTMIN + 13] = "SIGRT13",
+ [SIGRTMIN + 14] = "SIGRT14",
+ [SIGRTMIN + 15] = "SIGRT15",
+ [SIGRTMIN + 16] = "SIGRT16",
+ [SIGRTMIN + 17] = "SIGRT17",
+ [SIGRTMIN + 18] = "SIGRT18",
+ [SIGRTMIN + 19] = "SIGRT19",
+ [SIGRTMIN + 20] = "SIGRT20",
+ [SIGRTMIN + 21] = "SIGRT21",
+ [SIGRTMIN + 22] = "SIGRT22",
+ [SIGRTMIN + 23] = "SIGRT23",
+ [SIGRTMIN + 24] = "SIGRT24",
+ [SIGRTMIN + 25] = "SIGRT25",
+ [SIGRTMIN + 26] = "SIGRT26",
+ [SIGRTMIN + 27] = "SIGRT27",
+ [SIGRTMIN + 28] = "SIGRT28",
+ [SIGRTMIN + 29] = "SIGRT29",
+ [SIGRTMIN + 30] = "SIGRT30",
+ [SIGRTMIN + 31] = "SIGRT31",
+ [SIGRTMIN + 32] = "SIGRT32",
+ [SIGRTMIN + 33] = "SIGRT33",
+ [SIGRTMIN + 34] = "SIGRT34",
+ [SIGRTMIN + 35] = "SIGRT35",
+ [SIGRTMIN + 36] = "SIGRT36",
+ [SIGRTMIN + 37] = "SIGRT37",
+ [SIGRTMIN + 38] = "SIGRT38",
+ [SIGRTMIN + 39] = "SIGRT39",
+ [SIGRTMIN + 40] = "SIGRT40",
+ [SIGRTMIN + 41] = "SIGRT41",
+ [SIGRTMIN + 42] = "SIGRT42",
+ [SIGRTMIN + 43] = "SIGRT43",
+ [SIGRTMIN + 44] = "SIGRT44",
+ [SIGRTMIN + 45] = "SIGRT45",
+ [SIGRTMIN + 46] = "SIGRT46",
+ [SIGRTMIN + 47] = "SIGRT47",
+ [SIGRTMIN + 48] = "SIGRT48",
+ [SIGRTMIN + 49] = "SIGRT49",
+ [SIGRTMIN + 50] = "SIGRT50",
+ [SIGRTMIN + 51] = "SIGRT51",
+ [SIGRTMIN + 52] = "SIGRT52",
+ [SIGRTMIN + 53] = "SIGRT53",
+ [SIGRTMIN + 54] = "SIGRT54",
+ [SIGRTMIN + 55] = "SIGRT55",
+ [SIGRTMIN + 56] = "SIGRT56",
+ [SIGRTMIN + 57] = "SIGRT57",
+ [SIGRTMIN + 58] = "SIGRT58",
+ [SIGRTMIN + 59] = "SIGRT59",
+ [SIGRTMIN + 60] = "SIGRT60",
+ [SIGRTMIN + 61] = "SIGRT61",
+};
+
+const char *
+sysdecode_signal(int sig)
+{
+
+ if ((unsigned)sig < nitems(signames))
+ return (signames[sig]);
+ return (NULL);
+}
diff --git a/lib/libsysdecode/support.c b/lib/libsysdecode/support.c
new file mode 100644
index 000000000000..12c8b8875097
--- /dev/null
+++ b/lib/libsysdecode/support.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "support.h"
+
+const char *
+lookup_value(struct name_table *table, uintmax_t val)
+{
+
+ for (; table->str != NULL; table++)
+ if (table->val == val)
+ return (table->str);
+ return (NULL);
+}
+
+/*
+ * Used when the value maps to a bitmask of #definition values in the
+ * table. This is a helper routine which outputs a symbolic mask of
+ * matched masks. Multiple masks are separated by a pipe ('|').
+ * The value is modified on return to only hold unmatched bits.
+ */
+void
+print_mask_part(FILE *fp, struct name_table *table, uintmax_t *valp,
+ bool *printed)
+{
+ uintmax_t rem;
+
+ rem = *valp;
+ for (; table->str != NULL; table++) {
+ if ((table->val & rem) == table->val) {
+ /*
+ * Only print a zero mask if the raw value is
+ * zero.
+ */
+ if (table->val == 0 && *valp != 0)
+ continue;
+ fprintf(fp, "%s%s", *printed ? "|" : "", table->str);
+ *printed = true;
+ rem &= ~table->val;
+ }
+ }
+
+ *valp = rem;
+}
+
+/*
+ * Used when the value maps to a bitmask of #definition values in the
+ * table. The return value is true if something was printed. If
+ * rem is not NULL, *rem holds any bits not decoded if something was
+ * printed. If nothing was printed and rem is not NULL, *rem holds
+ * the original value.
+ */
+bool
+print_mask_int(FILE *fp, struct name_table *table, int ival, int *rem)
+{
+ uintmax_t val;
+ bool printed;
+
+ printed = false;
+ val = (unsigned)ival;
+ print_mask_part(fp, table, &val, &printed);
+ if (rem != NULL)
+ *rem = val;
+ return (printed);
+}
+
+/*
+ * Used for a mask of optional flags where a value of 0 is valid.
+ */
+bool
+print_mask_0(FILE *fp, struct name_table *table, int val, int *rem)
+{
+
+ if (val == 0) {
+ fputs("0", fp);
+ if (rem != NULL)
+ *rem = 0;
+ return (true);
+ }
+ return (print_mask_int(fp, table, val, rem));
+}
+
+/*
+ * Like print_mask_0 but for a unsigned long instead of an int.
+ */
+bool
+print_mask_0ul(FILE *fp, struct name_table *table, u_long lval, u_long *rem)
+{
+ uintmax_t val;
+ bool printed;
+
+ if (lval == 0) {
+ fputs("0", fp);
+ if (rem != NULL)
+ *rem = 0;
+ return (true);
+ }
+
+ printed = false;
+ val = lval;
+ print_mask_part(fp, table, &val, &printed);
+ if (rem != NULL)
+ *rem = val;
+ return (printed);
+}
+
+void
+print_integer(FILE *fp, int val, int base)
+{
+
+ switch (base) {
+ case 8:
+ fprintf(fp, "0%o", val);
+ break;
+ case 10:
+ fprintf(fp, "%d", val);
+ break;
+ case 16:
+ fprintf(fp, "0x%x", val);
+ break;
+ default:
+ abort2("bad base", 0, NULL);
+ break;
+ }
+}
+
+bool
+print_value(FILE *fp, struct name_table *table, uintmax_t val)
+{
+ const char *str;
+
+ str = lookup_value(table, val);
+ if (str != NULL) {
+ fputs(str, fp);
+ return (true);
+ }
+ return (false);
+}
diff --git a/lib/libsysdecode/support.h b/lib/libsysdecode/support.h
new file mode 100644
index 000000000000..fecb0bf1bb5e
--- /dev/null
+++ b/lib/libsysdecode/support.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __SYSDECODE_SUPPORT_H__
+#define __SYSDECODE_SUPPORT_H__
+
+/*
+ * This is taken from the xlat tables originally in truss which were
+ * in turn taken from strace.
+ */
+struct name_table {
+ uintmax_t val;
+ const char *str;
+};
+
+/*
+ * These are simple support macros. print_or utilizes a variable
+ * defined in the calling function to track whether or not it should
+ * print a logical-OR character ('|') before a string. if_print_or
+ * simply handles the necessary "if" statement used in many lines
+ * of this file.
+ */
+#define print_or(fp,str,orflag) do { \
+ if (orflag) fputc(fp, '|'); else orflag = true; \
+ fprintf(fp, str); } \
+ while (0)
+#define if_print_or(fp,i,flag,orflag) do { \
+ if ((i & flag) == flag) \
+ print_or(fp,#flag,orflag); } \
+ while (0)
+
+const char *lookup_value(struct name_table *, uintmax_t);
+void print_integer(FILE *, int, int);
+bool print_mask_0(FILE *, struct name_table *, int, int *);
+bool print_mask_0ul(FILE *, struct name_table *, u_long, u_long *);
+bool print_mask_int(FILE *, struct name_table *, int, int *);
+void print_mask_part(FILE *, struct name_table *, uintmax_t *, bool *);
+bool print_value(FILE *, struct name_table *, uintmax_t);
+
+#endif /* !__SYSDECODE_SUPPORT_H__ */
diff --git a/lib/libsysdecode/syscallnames.c b/lib/libsysdecode/syscallnames.c
new file mode 100644
index 000000000000..da356d8ac016
--- /dev/null
+++ b/lib/libsysdecode/syscallnames.c
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2015 John H. Baldwin <jhb@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+/*
+ * Map system call codes to names for the supported ABIs on each
+ * platform. Rather than regnerating system call name tables locally
+ * during the build, use the generated tables in the kernel source
+ * tree.
+ */
+
+#include <sys/param.h>
+#include <sys/acl.h>
+#include <sys/wait.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sysdecode.h>
+
+static
+#include <kern/syscalls.c>
+
+#if defined(__amd64__) || defined(__powerpc64__) || defined(__aarch64__)
+static
+#include <compat/freebsd32/freebsd32_syscalls.c>
+#endif
+
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+static
+#ifdef __aarch64__
+#include <arm64/linux/linux_syscalls.c>
+#elif __amd64__
+#include <amd64/linux/linux_syscalls.c>
+#else
+#include <i386/linux/linux_syscalls.c>
+#endif
+#endif
+
+#ifdef __amd64__
+static
+#include <amd64/linux32/linux32_syscalls.c>
+#endif
+
+const char *
+sysdecode_syscallname(enum sysdecode_abi abi, unsigned int code)
+{
+
+ switch (abi) {
+ case SYSDECODE_ABI_FREEBSD:
+ if (code < nitems(syscallnames))
+ return (syscallnames[code]);
+ break;
+#if defined(__amd64__) || defined(__powerpc64__) || defined(__aarch64__)
+ case SYSDECODE_ABI_FREEBSD32:
+ if (code < nitems(freebsd32_syscallnames))
+ return (freebsd32_syscallnames[code]);
+ break;
+#endif
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+ case SYSDECODE_ABI_LINUX:
+ if (code < nitems(linux_syscallnames))
+ return (linux_syscallnames[code]);
+ break;
+#endif
+#ifdef __amd64__
+ case SYSDECODE_ABI_LINUX32:
+ if (code < nitems(linux32_syscallnames))
+ return (linux32_syscallnames[code]);
+ break;
+#endif
+ default:
+ break;
+ }
+ return (NULL);
+}
diff --git a/lib/libsysdecode/sysdecode.3 b/lib/libsysdecode/sysdecode.3
new file mode 100644
index 000000000000..32f7fad4e6c5
--- /dev/null
+++ b/lib/libsysdecode/sysdecode.3
@@ -0,0 +1,82 @@
+.\"
+.\" Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd September 22, 2021
+.Dt SYSDECODE 3
+.Os
+.Sh NAME
+.Nm sysdecode
+.Nd system argument decoding library
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Sh DESCRIPTION
+The
+.Nm
+library includes several functions that provide descriptive names of
+values associated with system calls.
+.Ss Supported ABIs
+Some functions in this library provide ABI-specific descriptions.
+The supported ABIs are named by the
+.Vt enum sysdecode_abi
+enumeration.
+.Pp
+.Bl -tag -width "Li SYSDECODE_ABI_FREEBSD32" -compact
+.It Li SYSDECODE_ABI_FREEBSD
+Native FreeBSD binaries.
+Supported on all platforms.
+.It Li SYSDECODE_ABI_FREEBSD32
+32-bit FreeBSD binaries.
+Supported on aarch64, amd64 and powerpc64.
+.It Li SYSDECODE_ABI_LINUX
+Linux binaries of the same platform.
+Supported on amd64, i386, and aarch64.
+.It Li SYSDECODE_ABI_LINUX32
+32-bit Linux binaries.
+Supported on amd64.
+.It Li SYSDECODE_ABI_UNKNOWN
+A placeholder for use when the ABI is not known.
+.El
+.Sh SEE ALSO
+.Xr sysdecode_abi_to_freebsd_errno 3 ,
+.Xr sysdecode_cap_rights 3 ,
+.Xr sysdecode_cmsg_type 3 ,
+.Xr sysdecode_enum 3 ,
+.Xr sysdecode_fcntl_arg 3 ,
+.Xr sysdecode_ioctlname 3 ,
+.Xr sysdecode_kevent 3 ,
+.Xr sysdecode_mask 3 ,
+.Xr sysdecode_quotactl_cmd 3 ,
+.Xr sysdecode_sctp_sinfo_flags 3 ,
+.Xr sysdecode_sigcode 3 ,
+.Xr sysdecode_socket_protocol 3 ,
+.Xr sysdecode_sockopt_name 3 ,
+.Xr sysdecode_syscallname 3 ,
+.Xr sysdecode_utrace 3
+.Sh HISTORY
+The
+.Nm
+library first appeared in
+.Fx 11.0 .
diff --git a/lib/libsysdecode/sysdecode.h b/lib/libsysdecode/sysdecode.h
new file mode 100644
index 000000000000..c95d7f71379b
--- /dev/null
+++ b/lib/libsysdecode/sysdecode.h
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 2015 John H. Baldwin <jhb@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __SYSDECODE_H__
+#define __SYSDECODE_H__
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+enum sysdecode_abi {
+ SYSDECODE_ABI_UNKNOWN = 0,
+ SYSDECODE_ABI_FREEBSD,
+ SYSDECODE_ABI_FREEBSD32,
+ SYSDECODE_ABI_LINUX,
+ SYSDECODE_ABI_LINUX32,
+};
+
+int sysdecode_abi_to_freebsd_errno(enum sysdecode_abi _abi, int _error);
+bool sysdecode_access_mode(FILE *_fp, int _mode, int *_rem);
+const char *sysdecode_acltype(int _type);
+const char *sysdecode_atfd(int _fd);
+bool sysdecode_atflags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_cap_fcntlrights(FILE *_fp, uint32_t _rights, uint32_t *_rem);
+void sysdecode_cap_rights(FILE *_fp, cap_rights_t *_rightsp);
+bool sysdecode_close_range_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_cmsg_type(int _cmsg_level, int _cmsg_type);
+const char *sysdecode_extattrnamespace(int _namespace);
+const char *sysdecode_fadvice(int _advice);
+void sysdecode_fcntl_arg(FILE *_fp, int _cmd, uintptr_t _arg, int _base);
+bool sysdecode_fcntl_arg_p(int _cmd);
+const char *sysdecode_fcntl_cmd(int _cmd);
+bool sysdecode_fcntl_fileflags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_fileflags(FILE *_fp, fflags_t _flags, fflags_t *_rem);
+bool sysdecode_filemode(FILE *_fp, int _mode, int *_rem);
+bool sysdecode_flock_operation(FILE *_fp, int _operation, int *_rem);
+int sysdecode_freebsd_to_abi_errno(enum sysdecode_abi _abi, int _error);
+const char *sysdecode_getfsstat_mode(int _mode);
+const char *sysdecode_getrusage_who(int _who);
+const char *sysdecode_idtype(int _idtype);
+const char *sysdecode_ioctlname(unsigned long _val);
+bool sysdecode_inotifyflags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_ipproto(int _protocol);
+void sysdecode_kevent_fflags(FILE *_fp, short _filter, int _fflags,
+ int _base);
+const char *sysdecode_itimer(int _which);
+const char *sysdecode_kevent_filter(int _filter);
+bool sysdecode_kevent_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_kldsym_cmd(int _cmd);
+const char *sysdecode_kldunload_flags(int _flags);
+const char *sysdecode_lio_listio_mode(int _mode);
+const char *sysdecode_madvice(int _advice);
+const char *sysdecode_minherit_inherit(int _inherit);
+const char *sysdecode_msgctl_cmd(int _cmd);
+bool sysdecode_mlockall_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_mmap_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_mmap_prot(FILE *_fp, int _prot, int *_rem);
+bool sysdecode_mount_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_msg_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_msync_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_nfssvc_flags(int _flags);
+bool sysdecode_open_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_pathconf_name(int _name);
+bool sysdecode_pipe2_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_pollfd_events(FILE *fp, int flags, int *rem);
+const char *sysdecode_prio_which(int _which);
+const char *sysdecode_procctl_cmd(int _cmd);
+const char *sysdecode_ptrace_request(int _request);
+bool sysdecode_quotactl_cmd(FILE *_fp, int _cmd);
+bool sysdecode_reboot_howto(FILE *_fp, int _howto, int *_rem);
+bool sysdecode_rfork_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_rlimit(int _resource);
+const char *sysdecode_rtprio_function(int _function);
+const char *sysdecode_scheduler_policy(int _policy);
+bool sysdecode_sctp_nxt_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_sctp_pr_policy(int _policy);
+bool sysdecode_sctp_rcv_flags(FILE *_fp, int _flags, int *_rem);
+void sysdecode_sctp_sinfo_flags(FILE *_fp, int _sinfo_flags);
+bool sysdecode_sctp_snd_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_semctl_cmd(int _cmd);
+bool sysdecode_semget_flags(FILE *_fp, int _flag, int *_rem);
+bool sysdecode_sendfile_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_shmat_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_shmctl_cmd(int _cmd);
+const char *sysdecode_shutdown_how(int _how);
+const char *sysdecode_sigbus_code(int _si_code);
+const char *sysdecode_sigchld_code(int _si_code);
+const char *sysdecode_sigcode(int _sig, int _si_code);
+const char *sysdecode_sigfpe_code(int _si_code);
+const char *sysdecode_sigill_code(int _si_code);
+const char *sysdecode_signal(int _sig);
+const char *sysdecode_sigprocmask_how(int _how);
+const char *sysdecode_sigsegv_code(int _si_code);
+const char *sysdecode_sigtrap_code(int _si_code);
+const char *sysdecode_sockaddr_family(int _sa_family);
+const char *sysdecode_socketdomain(int _domain);
+const char *sysdecode_socket_protocol(int _domain, int _protocol);
+bool sysdecode_socket_type(FILE *_fp, int _type, int *_rem);
+const char *sysdecode_sockopt_level(int _level);
+const char *sysdecode_sockopt_name(int _level, int _optname);
+const char *sysdecode_syscallname(enum sysdecode_abi _abi, unsigned int _code);
+const char *sysdecode_sysarch_number(int _number);
+bool sysdecode_thr_create_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_umtx_cvwait_flags(FILE *_fp, u_long _flags, u_long *_rem);
+const char *sysdecode_umtx_op(int _op);
+bool sysdecode_umtx_op_flags(FILE *_fp, int op, int *_rem);
+bool sysdecode_umtx_rwlock_flags(FILE *_fp, u_long _flags, u_long *_rem);
+int sysdecode_utrace(FILE *_fp, void *_buf, size_t _len);
+bool sysdecode_vmprot(FILE *_fp, int _type, int *_rem);
+const char *sysdecode_vmresult(int _result);
+bool sysdecode_wait4_options(FILE *_fp, int _options, int *_rem);
+bool sysdecode_wait6_options(FILE *_fp, int _options, int *_rem);
+const char *sysdecode_whence(int _whence);
+bool sysdecode_shmflags(FILE *_fp, int _flags, int *_rem);
+
+#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
+
+#define SYSDECODE_HAVE_LINUX
+
+bool sysdecode_linux_atflags(FILE *_fp, int _flag, int *_rem);
+void sysdecode_linux_clockid(FILE *_fp, clockid_t _which);
+bool sysdecode_linux_clock_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_linux_clone_flags(FILE *_fp, int _flags, int *_rem);
+bool sysdecode_linux_open_flags(FILE *_fp, int _flags, int *_rem);
+const char *sysdecode_linux_signal(int _sig);
+const char *sysdecode_linux_sigprocmask_how(int _how);
+
+#endif /* __i386__ || __amd64__ || __aarch64__ */
+
+#endif /* !__SYSDECODE_H__ */
diff --git a/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 b/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3
new file mode 100644
index 000000000000..51955f062393
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3
@@ -0,0 +1,92 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd October 17, 2016
+.Dt sysdecode_abi_to_freebsd_errno 3
+.Os
+.Sh NAME
+.Nm sysdecode_abi_to_freebsd_errno ,
+.Nm sysdecode_freebsd_to_abi_errno
+.Nd translate error numbers between process ABIs
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft int
+.Fn sysdecode_abi_to_freebsd_errno "enum sysdecode_abi abi" "int error"
+.Ft int
+.Fn sysdecode_freebsd_to_abi_errno "enum sysdecode_abi abi" "int error"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_abi_to_freebsd_errno
+function returns the native
+.Xr errno 2
+value that corresponds to the error indicated by
+.Fa error
+for the process ABI
+.Fa abi .
+If
+.Fa error
+does not identify a valid error for
+.Fa abi ,
+.Dv INT_MAX
+is returned.
+.Pp
+The
+.Fn sysdecode_freebsd_to_abi_errno
+function the error value for the process ABI
+.Fa abi
+that corresponds to the native
+.Xr errno 2
+value
+.Fa error .
+If
+.Fa error
+does not identify a valid
+.Xr errno 2
+error,
+.Dv INT_MAX
+is returned.
+.Pp
+Note that the mappings between native
+.Xr errno 2
+values and errors for other ABIs are not exhaustive.
+If a mapping does not exist,
+these functions return
+.Dv INT_MAX .
+In addition, multiple error values in one ABI may map to a single
+error in another ABI.
+.Sh RETURN VALUES
+These functions return an error value on success or
+.Dv INT_MAX
+if
+.Fa error
+is not valid.
+.Pp
+For the list of supported ABIs,
+see
+.Xr sysdecode 3 .
+.Sh SEE ALSO
+.Xr sysdecode 3 ,
+.Xr sysdecode_syscallname 3
diff --git a/lib/libsysdecode/sysdecode_cap_rights.3 b/lib/libsysdecode/sysdecode_cap_rights.3
new file mode 100644
index 000000000000..c03b305f3dc6
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_cap_rights.3
@@ -0,0 +1,66 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd April 11, 2022
+.Dt sysdecode_cap_rights 3
+.Os
+.Sh NAME
+.Nm sysdecode_cap_rights
+.Nd output list of capability rights
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft void
+.Fn sysdecode_cap_rights "FILE *fp" "cap_rights_t *rightsp"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_cap_rights
+function outputs a comma-separated list of capability rights at
+.Fa rightsp
+to the stream
+.Fa fp .
+.Pp
+Note that some capability rights are supersets of others; for example,
+.Dv CAP_PREAD
+is the union of
+.Dv CAP_READ
+and
+.Dv CAP_SEEK .
+.Fn sysdecode_cap_rights
+emits a minimal list of rights whose union is equal to
+.Fa *rightsp .
+For example, if both
+.Dv CAP_READ
+and
+.Dv CAP_SEEK
+are set in
+.Fa *rightsp ,
+then
+.Fn sysdecode_cap_rights
+will include only
+.Dv CAP_PREAD
+in the output list.
+.Sh SEE ALSO
+.Xr sysdecode 3
diff --git a/lib/libsysdecode/sysdecode_cmsg_type.3 b/lib/libsysdecode/sysdecode_cmsg_type.3
new file mode 100644
index 000000000000..574b7c1e94b0
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_cmsg_type.3
@@ -0,0 +1,50 @@
+.\"
+.\" Copyright (c) 2018 Michael Tuexen <tuexen@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd January 15, 2018
+.Dt sysdecode_cmsg_type 3
+.Os
+.Sh NAME
+.Nm sysdecode_cmsg_type
+.Nd lookup name of cmsg type
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft const char *
+.Fn sysdecode_cmsg_type "int cmsg_level" "int cmsg_type"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_cmsg_type
+function returns a text description of the
+.Fa cmsg_type
+member of a
+.Vt struct cmsghdr .
+.Fn sysdecode_cmsg_type
+also takes the
+.Fa cmsg_level
+to uniquely identify the type.
+.Sh SEE ALSO
+.Xr sysdecode 3
diff --git a/lib/libsysdecode/sysdecode_enum.3 b/lib/libsysdecode/sysdecode_enum.3
new file mode 100644
index 000000000000..f4cbcdd1e784
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_enum.3
@@ -0,0 +1,259 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd June 22, 2022
+.Dt sysdecode_enum 3
+.Os
+.Sh NAME
+.Nm sysdecode_enum ,
+.Nm sysdecode_acltype ,
+.Nm sysdecode_atfd ,
+.Nm sysdecode_extattrnamespace ,
+.Nm sysdecode_fadvice ,
+.Nm sysdecode_fcntl_cmd ,
+.Nm sysdecode_getfsstat_mode ,
+.Nm sysdecode_getrusage_who ,
+.Nm sysdecode_idtype ,
+.Nm sysdecode_ipproto ,
+.Nm sysdecode_itimer ,
+.Nm sysdecode_kldsym_cmd ,
+.Nm sysdecode_kldunload_flags ,
+.Nm sysdecode_lio_listio_mode ,
+.Nm sysdecode_madvice ,
+.Nm sysdecode_minherit_flags ,
+.Nm sysdecode_msgctl_cmd ,
+.Nm sysdecode_nfssvc_flags ,
+.Nm sysdecode_pathconf_name ,
+.Nm sysdecode_prio_which ,
+.Nm sysdecode_procctl_cmd ,
+.Nm sysdecode_ptrace_request ,
+.Nm sysdecode_rlimit ,
+.Nm sysdecode_rtprio_function ,
+.Nm sysdecode_scheduler_policy ,
+.Nm sysdecode_sctp_pr_policy ,
+.Nm sysdecode_sctp_sinfo_flags ,
+.Nm sysdecode_semctl_cmd ,
+.Nm sysdecode_shmctl_cmd ,
+.Nm sysdecode_shutdown_how ,
+.Nm sysdecode_sigbus_code ,
+.Nm sysdecode_sigchld_code ,
+.Nm sysdecode_sigfpe_code ,
+.Nm sysdecode_sigill_code ,
+.Nm sysdecode_signal ,
+.Nm sysdecode_sigprocmask_how ,
+.Nm sysdecode_sigsegv_code ,
+.Nm sysdecode_sigtrap_code ,
+.Nm sysdecode_sockaddr_family ,
+.Nm sysdecode_socketdomain ,
+.Nm sysdecode_sockettype ,
+.Nm sysdecode_sockopt_level ,
+.Nm sysdecode_sysarch_number ,
+.Nm sysdecode_umtx_op ,
+.Nm sysdecode_vmresult ,
+.Nm sysdecode_whence
+.Nd lookup name of various enumerated values
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft const char *
+.Fn sysdecode_acltype "int type"
+.Ft const char *
+.Fn sysdecode_atfd "int fd"
+.Ft const char *
+.Fn sysdecode_extattrnamespace "int namespace"
+.Ft const char *
+.Fn sysdecode_fadvice "int advice"
+.Ft const char *
+.Fn sysdecode_fcntl_cmd "int cmd"
+.Ft const char *
+.Fn sysdecode_getfsstat_mode "int mode"
+.Ft const char *
+.Fn sysdecode_getrusage_who "int who"
+.Ft const char *
+.Fn sysdecode_idtype "int idtype"
+.Ft const char *
+.Fn sysdecode_ipproto "int protocol"
+.Ft const char *
+.Fn sysdecode_itimer "int which"
+.Ft const char *
+.Fn sysdecode_kldsym_cmd "int cmd"
+.Ft const char *
+.Fn sysdecode_kldunload_flags "int flags"
+.Ft const char *
+.Fn sysdecode_lio_listio_mode "int mode"
+.Ft const char *
+.Fn sysdecode_madvice "int advice"
+.Ft const char *
+.Fn sysdecode_minherit_flags "int inherit"
+.Ft const char *
+.Fn sysdecode_msgctl_cmd "int cmd"
+.Ft const char *
+.Fn sysdecode_nfssvc_flags "int flags"
+.Ft const char *
+.Fn sysdecode_pathconf_name "int name"
+.Ft const char *
+.Fn sysdecode_prio_which "int which"
+.Ft const char *
+.Fn sysdecode_procctl_cmd "int cmd"
+.Ft const char *
+.Fn sysdecode_ptrace_request "int request"
+.Ft const char *
+.Fn sysdecode_rlimit "int resource"
+.Ft const char *
+.Fn sysdecode_rtprio_function "int function"
+.Ft const char *
+.Fn sysdecode_scheduler_policy "int policy"
+.Ft const char *
+.Fn sysdecode_sctp_pr_policy "int policy"
+.Ft const char *
+.Fn sysdecode_semctl_cmd "int cmd"
+.Ft const char *
+.Fn sysdecode_shmctl_cmd "int cmd"
+.Ft const char *
+.Fn sysdecode_shutdown_how "int how"
+.Ft const char *
+.Fn sysdecode_sigbus_code "int si_code"
+.Ft const char *
+.Fn sysdecode_sigchld_code "int si_code"
+.Ft const char *
+.Fn sysdecode_sigfpe_code "int si_code"
+.Ft const char *
+.Fn sysdecode_sigill_code "int si_code"
+.Ft const char *
+.Fn sysdecode_signal "int sig"
+.Ft const char *
+.Fn sysdecode_sigprocmask_how "int how"
+.Ft const char *
+.Fn sysdecode_sigsegv_code "int si_code"
+.Ft const char *
+.Fn sysdecode_sigtrap_code "int si_code"
+.Ft const char *
+.Fn sysdecode_sockaddr_family "int sa_family"
+.Ft const char *
+.Fn sysdecode_socketdomain "int domain"
+.Ft const char *
+.Fn sysdecode_sockettype "int type"
+.Ft const char *
+.Fn sysdecode_sockopt_level "int level"
+.Ft const char *
+.Fn sysdecode_sysarch_number "int number"
+.Ft const char *
+.Fn sysdecode_umtx_op "int op"
+.Ft const char *
+.Fn sysdecode_vmresult "int result"
+.Ft const char *
+.Fn sysdecode_whence "int whence"
+.Sh DESCRIPTION
+The
+.Nm
+functions return a text description of an integer value.
+The text description matches the name of a C macro with the same value as the
+sole function argument.
+.Dv NULL
+is returned if there is no matching C macro name.
+.Pp
+Most of these functions decode an argument passed to a system call:
+.Bl -column "Fn sysdecode_extattrnamespace" "Xr sched_setscheduler 2"
+.It Sy Function Ta Sy System Call Ta Sy Argument
+.It Fn sysdecode_acltype Ta Xr acl_get_file 3 Ta Fa type
+.It Fn sysdecode_atfd Ta Xr openat 2 Ta Fa fd
+.It Fn sysdecode_extattrnamespace Ta Xr extattr_get_fd 2 Ta Fa attrnamespace
+.It Fn sysdecode_fadvice Ta Xr posix_fadvise 2 Ta Fa advice
+.It Fn sysdecode_fcntl_cmd Ta Xr fcntl 2 Ta Fa cmd
+.It Fn sysdecode_getfsstat_mode Ta Xr getfsstat 2 Ta Fa mode
+.It Fn sysdecode_idtype Ta
+.Xr procctl 2 ,
+.Xr waitid 2
+.Ta Fa idtype
+.It Fn sysdecode_itimer Ta
+.Xr getitimer 2 ,
+.Xr setitimer 2
+.Ta Fa which
+.It Fn sysdecode_kldsym_cmd Ta Xr kldsym 2 Ta Fa cmd
+.It Fn sysdecode_kldunload_flags Ta Xr kldunloadf 2 Ta Fa flags
+.It Fn sysdecode_lio_listio_mode Ta Xr lio_listio 2 Ta Fa mode
+.It Fn sysdecode_madvice Ta Xr madvise 2 Ta Fa advice
+.It Fn sysdecode_minherit_inherit Ta Xr minherit 2 Ta Fa inherit
+.It Fn sysdecode_msgctl_cmd Ta Xr msgctl 2 Ta Fa cmd
+.It Fn sysdecode_nfssvc_flags Ta Xr nfssvc 2 Ta Fa flags
+.It Fn sysdecode_pathconf_name Ta Xr pathconf 2 Ta Fa name
+.It Fn sysdecode_prio_which Ta Xr getpriority 2 Ta Fa which
+.It Fn sysdecode_procctl_cmd Ta Xr procctl 2 Ta Fa cmd
+.It Fn sysdecode_ptrace_request Ta Xr ptrace 2 Ta Fa request
+.It Fn sysdecode_rlimit Ta Xr getrlimit 2 Ta Fa resource
+.It Fn sysdecode_rtprio_function Ta Xr rtprio 2 Ta Fa function
+.It Fn sysdecode_getrusage_who Ta Xr getrusage 2 Ta Fa who
+.It Fn sysdecode_scheduler_policy Ta Xr sched_setscheduler 2 Ta Fa policy
+.It Fn sysdecode_semctl_cmd Ta Xr semctl 2 Ta Fa cmd
+.It Fn sysdecode_shmctl_cmd Ta Xr shmctl 2 Ta Fa cmd
+.It Fn sysdecode_shutdown_how Ta Xr shutdown 2 Ta Fa how
+.It Fn sysdecode_sigprocmask_how Ta Xr sigprocmask 2 Ta Fa how
+.It Fn sysdecode_sockopt_level Ta Xr getsockopt 2 Ta Fa level
+.It Fn sysdecode_sysarch_number Ta Xr sysarch 2 Ta Fa number
+.It Fn sysdecode_umtx_op Ta Xr _umtx_op 2 Ta Fa op
+.It Fn sysdecode_whence Ta Xr lseek 2 Ta Fa whence
+.El
+.Pp
+These functions decode signal-specific signal codes stored in the
+.Fa si_code
+field of the
+.Vt siginfo_t
+object associated with an instance of signal:
+.Bl -column "Fn sysdecode_sigchld_code"
+.It Sy Function Ta Sy Signal
+.It Fn sysdecode_sigbus_code Ta Dv SIGBUS
+.It Fn sysdecode_sigchld_code Ta Dv SIGCHLD
+.It Fn sysdecode_sigfpe_code Ta Dv SIGFPE
+.It Fn sysdecode_sigill_code Ta Dv SIGILL
+.It Fn sysdecode_sigsegv_code Ta Dv SIGSEGV
+.It Fn sysdecode_sigtrap_code Ta Dv SIGTRAP
+.El
+.Pp
+Other functions decode the values described below:
+.Bl -tag -width "Fn sysdecode_sockaddr_family"
+.It Fn sysdecode_ipproto
+An IP protocol.
+.It Fn sysdecode_sctp_pr_policy
+A PR-SCTP policy.
+.It Fn sysdecode_signal
+A process signal.
+.It Fn sysdecode_sockaddr_family
+A socket address family.
+.It Fn sysdecode_socketdomain
+A socket domain.
+.It Fn sysdecode_vmresult
+The return value of a function in the virtual memory subsystem of the kernel
+indicating the status of the associated request.
+.El
+.Sh RETURN VALUES
+The
+.Nm
+functions return the name of a matching C macro or
+.Dv NULL
+if no matching C macro was found.
+.Sh SEE ALSO
+.Xr sysdecode 3 ,
+.Xr sysdecode_mask 3 ,
+.Xr sysdecode_sigcode 3
diff --git a/lib/libsysdecode/sysdecode_fcntl_arg.3 b/lib/libsysdecode/sysdecode_fcntl_arg.3
new file mode 100644
index 000000000000..d5648ce0adc3
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_fcntl_arg.3
@@ -0,0 +1,117 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd November 24, 2017
+.Dt sysdecode_fcntl_arg 3
+.Os
+.Sh NAME
+.Nm sysdecode_fcntl_arg ,
+.Nm sysdecode_fcntl_arg_p
+.Nd output description of fcntl argument
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft void
+.Fn sysdecode_fcntl_arg "FILE *fp" "int cmd" "uintptr_t arg" "int base"
+.Ft bool
+.Fn sysdecode_fcntl_arg_p "int cmd"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_fcntl_arg
+function outputs a text description of the optional
+.Fa arg
+argument to
+.Xr fcntl 2
+to the stream
+.Fa fp .
+The type and format of
+.Fa arg
+are determined by
+.Fa cmd :
+.Bl -column ".Dv F_SETLKW" "Vt struct flock *"
+.It Sy Command Ta Fa arg Sy Type Ta Sy Output Format
+.It
+.It Dv F_SETFD Ta Vt int Ta
+.Dq FD_CLOEXEC ,
+.Dq FD_CLOFORK
+or the value of
+.Fa arg
+in the indicated
+.Fa base
+.Pq one of 8, 10, or 16 .
+.It
+.It Dv F_SETFL Ta Vt int Ta
+File flags as output by
+.Xr sysdecode_fcntl_fileflags 3
+with any unknown or remaining bits output in hexadecimal.
+.It
+.It Dv F_GETLK Ta Vt struct flock * Ta
+.It Dv F_SETLK Ta Vt struct flock * Ta
+.It Dv F_SETLKW Ta Vt struct flock * Ta
+The value of
+.Fa arg
+using the
+.Dq %p
+conversion specification.
+.It
+.It Others Ta Vt int Ta
+The value of
+.Fa arg
+in the indicated
+.Fa base
+.Pq one of 8, 10, or 16 .
+.El
+.Pp
+The
+.Fn sysdecode_fcntl_arg_p
+function can be used to determine if a
+.Xr fcntl 2
+command uses the optional third argument to
+.Xr fcntl 2 .
+The function returns
+.Dv true
+if
+.Fa cmd
+accepts a third argument to
+.Xr fcntl 2
+and
+.Dv false
+if it does not.
+.Sh RETURN VALUES
+The
+.Nm sysdecode_fcntl_arg_p
+function returns
+.Dv true
+if
+.Fa cmd
+accepts a third argument to
+.Xr fcntl 2
+and
+.Dv false
+if it does not.
+.Sh SEE ALSO
+.Xr sysdecode 3 ,
+.Xr sysdecode_fcntl_cmd 3 ,
+.Xr sysdecode_fcntl_fileflags 3
diff --git a/lib/libsysdecode/sysdecode_ioctlname.3 b/lib/libsysdecode/sysdecode_ioctlname.3
new file mode 100644
index 000000000000..c7e8737d93fa
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_ioctlname.3
@@ -0,0 +1,55 @@
+.\"
+.\" Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd October 17, 2016
+.Dt sysdecode_ioctlname 3
+.Os
+.Sh NAME
+.Nm sysdecode_ioctlname
+.Nd lookup name of device control command
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft const char *
+.Fn sysdecode_ioctlname "unsigned long request"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_ioctlname
+function returns the name of a device control request identified by
+.Fa request .
+A table of names is generated during the build of the
+.Nm sysdecode
+library from system headers that maps device control request values to
+the name of the corresponding C macro.
+.Sh RETURN VALUES
+The
+.Fn sysdecode_ioctlname
+function returns the name of a device control request if
+.Fa request
+is a known value;
+otherwise
+.Dv NULL .
+.Sh SEE ALSO
+.Xr sysdecode 3
diff --git a/lib/libsysdecode/sysdecode_kevent.3 b/lib/libsysdecode/sysdecode_kevent.3
new file mode 100644
index 000000000000..b96bcf12e41b
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_kevent.3
@@ -0,0 +1,120 @@
+.\"
+.\" Copyright (c) 2017 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd November 24, 2017
+.Dt sysdecode_kevent 3
+.Os
+.Sh NAME
+.Nm sysdecode_kevent ,
+.Nm sysdecode_kevent_fflags ,
+.Nm sysdecode_kevent_filter ,
+.Nm sysdecode_kevent_flags
+.Nd output description of kevent structure fields
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft void
+.Fn sysdecode_kevent_fflags "FILE *fp" "short filter" "int fflags" "int base"
+.Ft bool
+.Fn sysdecode_kevent_flags "FILE *fp" "int flags" "int *rem"
+.Ft const char *
+.Fn sysdecode_kevent_filter "int filter"
+.Sh DESCRIPTION
+These functions provide text descriptions of
+.Vt struct kevent
+fields.
+.Pp
+The
+.Fn sysdecode_kevent_fflags
+function outputs a text description of the
+.Fa fflags
+member of a
+.Vt struct kevent
+to the stream
+.Fa fp .
+For the
+.Dv EVFILT_READ ,
+.Dv EVFILT_WRITE ,
+.Dv EVFILT_VNODE ,
+.Dv EVFILT_PROC ,
+.Dv EVFILT_PROCDESC ,
+.Dv EVFILT_TIMER ,
+and
+.Dv EVFILT_USER
+filters,
+.Fn sysdecode_kevent_fflags
+outputs a bitmask of filter-specific
+.Dv NOTE_*
+flags as documented in
+.Xr kevent 2 .
+For other values of
+.Fa filter ,
+the value of
+.Fa fflags
+is output in the indicated
+.Fa base
+.Pq one of 8, 10, or 16 .
+.Pp
+The
+.Fn sysdecode_kevent_filter
+function returns a text description of the
+.Fa filter
+member of a
+.Vt struct kevent .
+.Dv NULL
+is returned if the
+.Fa filter
+value is unknown.
+.Pp
+The
+.Fn sysdecode_kevent_flags
+function outputs a text description of the
+.Fa flags
+member of a
+.Vt struct kevent
+to the stream
+.Fa fp .
+This function uses the same calling convention and formatting as the other
+functions described in
+.Xr sysdecode_mask 3 .
+.Sh RETURN VALUES
+The
+.Nm sysdecode_kevent_filter
+function returns the name of a filter or
+.Dv NULL if the filter value is unknown.
+.Pp
+The
+.Nm sysdecode_kevent_flags
+function returns
+.Dv true
+if any flags in the
+.Fa flags
+field were decoded and
+.Dv false
+if no flags were decoded.
+.Sh SEE ALSO
+.Xr sysdecode 3 ,
+.Xr sysdecode_enum 3 ,
+.Xr sysdecode_mask 3
diff --git a/lib/libsysdecode/sysdecode_mask.3 b/lib/libsysdecode/sysdecode_mask.3
new file mode 100644
index 000000000000..efcab331fe29
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_mask.3
@@ -0,0 +1,250 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd February 29, 2024
+.Dt sysdecode_mask 3
+.Os
+.Sh NAME
+.Nm sysdecode_mask ,
+.Nm sysdecode_accessmode ,
+.Nm sysdecode_atflags ,
+.Nm sysdecode_capfcntlrights ,
+.Nm sysdecode_close_range_flags ,
+.Nm sysdecode_fcntl_fileflags ,
+.Nm sysdecode_fileflags ,
+.Nm sysdecode_filemode ,
+.Nm sysdecode_flock_operation ,
+.Nm sysdecode_mlockall_flags ,
+.Nm sysdecode_mmap_flags ,
+.Nm sysdecode_mmap_prot ,
+.Nm sysdecode_mount_flags ,
+.Nm sysdecode_msg_flags ,
+.Nm sysdecode_msync_flags ,
+.Nm sysdecode_open_flags ,
+.Nm sysdecode_pipe2_flags ,
+.Nm sysdecode_pollfd_events ,
+.Nm sysdecode_reboot_howto ,
+.Nm sysdecode_rfork_flags ,
+.Nm sysdecode_semget_flags ,
+.Nm sysdecode_sendfile_flags ,
+.Nm sysdecode_shmat_flags ,
+.Nm sysdecode_sctp_nxt_flags ,
+.Nm sysdecode_sctp_rcv_flags ,
+.Nm sysdecode_sctp_snd_flags ,
+.Nm sysdecode_socket_type ,
+.Nm sysdecode_thr_create_flags ,
+.Nm sysdecode_umtx_cvwait_flags ,
+.Nm sysdecode_umtx_rwlock_flags ,
+.Nm sysdecode_vmprot ,
+.Nm sysdecode_wait4_options ,
+.Nm sysdecode_wait6_options
+.Nd print name of various bitmask values
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft bool
+.Fn sysdecode_access_mode "FILE *fp" "int mode" "int *rem"
+.Ft bool
+.Fn sysdecode_atflags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_cap_fcntlrights "FILE *fp" "uint32_t rights" "uint32_t *rem"
+.Ft bool
+.Fn sysdecode_close_range_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_fcntl_fileflags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_fileflags "FILE *fp" "fflags_t flags" "fflags_t *rem"
+.Ft bool
+.Fn sysdecode_filemode "FILE *fp" "int mode" "int *rem"
+.Ft bool
+.Fn sysdecode_flock_operation "FILE *fp" "int operation" "int *rem"
+.Ft bool
+.Fn sysdecode_mlockall_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_mmap_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_mmap_prot "FILE *fp" "int prot" "int *rem"
+.Ft bool
+.Fn sysdecode_mount_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_msg_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_msync_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_open_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_pipe2_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_pollfd_events "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_reboot_howto "FILE *fp" "int howto" "int *rem"
+.Ft bool
+.Fn sysdecode_rfork_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_sctp_nxt_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_sctp_rcv_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_sctp_snd_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_semget_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_sendfile_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_shmat_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_socket_type "FILE *fp" "int type" "int *rem"
+.Ft bool
+.Fn sysdecode_thr_create_flags "FILE *fp" "int flags" "int *rem"
+.Ft bool
+.Fn sysdecode_umtx_cvwait_flags "FILE *fp" "u_long flags" "u_long *rem"
+.Ft bool
+.Fn sysdecode_umtx_rwlock_flags "FILE *fp" "u_long flags" "u_long *rem"
+.Ft bool
+.Fn sysdecode_vmprot "FILE *fp" "int type" "int *rem"
+.Ft bool
+.Fn sysdecode_wait4_options "FILE *fp" "int options" "int *rem"
+.Ft bool
+.Fn sysdecode_wait6_options "FILE *fp" "int options" "int *rem"
+.Sh DESCRIPTION
+The
+.Nm
+functions are used to generate a text description of an integer value
+built from a mask of bitfields.
+The text description lists the C macros for field values joined by pipe
+.Sq |
+characters matching the format used in C source code.
+Most of the values decoded by these functions are passed as arguments to
+system calls,
+though some of these values are used internally in the kernel.
+.Pp
+Each function writes the text description to
+.Fa fp .
+The second argument should contain the integer value to be decoded.
+The
+.Fa rem
+argument is set to the value of any bits that were not decoded
+.Pq bit fields that do not have a corresponding C macro .
+.Fa rem
+may be set to
+.Dv NULL
+if the caller does not need this value.
+Each function returns
+.Dv true
+if any bit fields in the value were decoded and
+.Dv false
+if no bit fields were decoded.
+.Pp
+Most of these functions decode an argument passed to a system call:
+.Bl -column "Fn sysdecode_flock_operation" "Xr cap_fcntls_limit 2"
+.It Sy Function Ta Sy System Call Ta Sy Argument
+.It Fn sysdecode_access_mode Ta Xr access 2 Ta Fa mode
+.It Fn sysdecode_atflags Ta Xr chflagsat 2 , Xr fstatat 2 Ta Fa atflag , Fa flag
+.It Fn sysdecode_cap_fcntlrights Ta Xr cap_fcntls_limit 2 Ta Fa fcntlrights
+.It Fn sysdecode_fileflags Ta Xr chflags 2 Ta Fa flags
+.It Fn sysdecode_filemode Ta Xr chmod 2 , Xr open 2 Ta mode
+.It Fn sysdecode_flock_operation Ta Xr flock 2 Ta Fa operation
+.It Fn sysdecode_mlockall_flags Ta Xr mlockall 2 Ta Fa flags
+.It Fn sysdecode_mmap_flags Ta Xr mmap 2 Ta Fa flags
+.It Fn sysdecode_mmap_prot Ta Xr mmap 2 Ta Fa prot
+.It Fn sysdecode_mount_flags Ta Xr mount 2 Ta Fa flags
+.It Fn sysdecode_msg_flags Ta Xr recv 2 , Xr send 2 Ta Fa flags
+.It Fn sysdecode_msync_flags Ta Xr msync 2 Ta Fa flags
+.It Fn sysdecode_open_flags Ta Xr open 2 Ta Fa flags
+.It Fn sysdecode_pipe2_flags Ta Xr pipe2 Ta Fa flags
+.It Fn sysdecode_reboot_howto Ta Xr reboot 2 Ta Fa howto
+.It Fn sysdecode_rfork_flags Ta Xr rfork 2 Ta Fa flags
+.It Fn sysdecode_semget_flags Ta Xr semget 2 Ta Fa flags
+.It Fn sysdecode_sendfile_flags Ta Xr sendfile 2 Ta Fa flags
+.It Fn sysdecode_shmat_flags Ta Xr shmat 2 Ta Fa flags
+.It Fn sysdecode_socket_type Ta Xr socket 2 Ta Fa type
+.It Fn sysdecode_thr_create_flags Ta Xr thr_create 2 Ta Fa flags
+.It Fn sysdecode_wait4_options Ta Xr wait4 2 Ta Fa options
+.It Fn sysdecode_wait6_options Ta Xr wait6 2 Ta Fa options
+.El
+.Pp
+Other functions decode the values described below:
+.Bl -tag -width ".Fn sysdecode_umtx_cvwait_flags"
+.It Fn sysdecode_fcntl_fileflags
+The file flags used with the
+.Dv F_GETFL
+and
+.Dv F_SETFL
+.Xr fcntl 2
+commands.
+.It Fn sysdecode_pollfd_events
+The
+.Fa events
+and
+.Fa revents
+members of a
+.Vt struct pollfd .
+.It Fn sysdecode_sctp_nxt_flags
+The
+.Fa nxt_flags
+member of a
+.Vt struct sctp_nxtinfo .
+.It Fn sysdecode_sctp_rcv_flags
+The
+.Fa rcv_flags
+member of a
+.Vt struct sctp_rcvinfo .
+.It Fn sysdecode_sctp_snd_flags
+The
+.Fa snd_flags
+member of a
+.Vt struct sctp_sndinfo .
+.It Fn sysdecode_umtx_cvwait_flags
+The
+.Fa val
+argument to
+.Xr _umtx_op 2
+for
+.Dv UMTX_OP_CV_WAIT
+operations.
+.It Fn sysdecode_umtx_rwlock_flags
+The
+.Fa val
+argument to
+.Xr _umtx_op 2
+for
+.Dv UMTX_OP_RW_RDLOCK
+operations.
+.It Fn sysdecode_vmprot
+The memory protection flags stored in
+.Vt vm_prot_t
+variables.
+.El
+.Sh RETURN VALUES
+The
+.Nm
+functions return
+.Dv true
+if any bit fields in the value were decoded and
+.Dv false
+if no bit fields were decoded.
+.Sh SEE ALSO
+.Xr sysdecode 3 ,
+.Xr sysdecode_enum 3
diff --git a/lib/libsysdecode/sysdecode_quotactl_cmd.3 b/lib/libsysdecode/sysdecode_quotactl_cmd.3
new file mode 100644
index 000000000000..f30d409616dd
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_quotactl_cmd.3
@@ -0,0 +1,88 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd November 24, 2017
+.Dt sysdecode_quotactl_cmd 3
+.Os
+.Sh NAME
+.Nm sysdecode_quotactl_cmd
+.Nd output name of quotactl command
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft bool
+.Fn sysdecode_quotactl_cmd "FILE *fp" "int cmd"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_quotactl_cmd
+function outputs a text description of the
+.Fa cmd
+argument to
+.Xr quotactl 2
+to the stream
+.Fa fp .
+The description is formatted as an invocation of the
+.Dv QCMD
+macro defined in the
+.In ufs/ufs/quota.h
+header.
+.Pp
+The function first computes the primary and secondary values used by
+.Dv QCMD
+to construct
+.Fa cmd .
+If the primary command value does not represent a known constant,
+.Fn sysdecode_quotactl_cmd
+does not generate any output and returns
+.Dv false .
+Otherwise,
+.Fn sysdecode_quotactl_cmd
+outputs text depicting an invocation of
+.Dv QCMD
+with the associated constants for the primary and secondary command values
+and returns
+.Dv true .
+If the secondary command values does not represent a known constant,
+its value is output as a hexadecimal integer.
+.Sh RETURN VALUES
+The
+.Nm sysdecode_quotactl_cmd
+function returns
+.Dv true
+if it outputs a description of
+.Fa cmd
+and
+.Dv false
+if it does not.
+.Sh EXAMPLES
+The statement
+.Pp
+.Dl sysdecode_quotatcl_cmd(stdout, QCMD(Q_GETQUOTA, USRQUOTA);
+.Pp
+outputs the text
+.Dq QCMD(Q_GETQUOTA, USRQUOTA)
+to standard output.
+.Sh SEE ALSO
+.Xr sysdecode 3
diff --git a/lib/libsysdecode/sysdecode_sctp_sinfo_flags.3 b/lib/libsysdecode/sysdecode_sctp_sinfo_flags.3
new file mode 100644
index 000000000000..4eb25187f0d0
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_sctp_sinfo_flags.3
@@ -0,0 +1,50 @@
+.\"
+.\" Copyright (c) 2018 Michael Tuexen <tuexen@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd January 14, 2018
+.Dt sysdecode_sctp_sinfo_flags 3
+.Os
+.Sh NAME
+.Nm sysdecode_sctp_sinfo_flags
+.Nd output textual description of the sinfo_flags field of struct sctp_sndrcvinfo
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft void
+.Fn sysdecode_sctp_sinfo_flags "FILE *fp" "int sinfo_flags"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_sctp_sinfo_flags
+function outputs a textual description of the
+.Fa sinfo_flags
+member of a
+.Vt struct sctp_sndrcvinfo
+to the stream
+.Fa fp .
+In particular, the embedded PR-SCTP policies are handled.
+.Sh SEE ALSO
+.Xr sysdecode 3 ,
+.Xr sysdecode_sctp_pr_policy 3
diff --git a/lib/libsysdecode/sysdecode_sigcode.3 b/lib/libsysdecode/sysdecode_sigcode.3
new file mode 100644
index 000000000000..41adef246b74
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_sigcode.3
@@ -0,0 +1,78 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd October 17, 2016
+.Dt sysdecode_sigcode 3
+.Os
+.Sh NAME
+.Nm sysdecode_sigcode
+.Nd lookup name of signal code
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft const char *
+.Fn sysdecode_sigcode "int signal" "int si_code"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_sigcode
+function returns a text description of the
+.Fa si_code
+field of the
+.Vt siginfo_t
+object associated with an instance of signal
+.Fa sig .
+The text description contains the name of the C macro whose value matches
+.Fa si_code .
+General purpose signal codes such as
+.Dv SI_USER
+are handled as well as signal-specific codes for
+.Dv SIGBUS ,
+.Dv SIGCHLD ,
+.Dv SIGFPE ,
+.Dv SIGILL ,
+.Dv SIGSEGV
+and
+.Dv SIGTRAP .
+If
+.Fa si_code
+does not represent a known signal code,
+.Fn sysdecode_sigcode
+returns
+.Dv NULL .
+.Sh RETURN VALUES
+The
+.Fn sysdecode_sigcode
+function returns a pointer to a signal code description or
+.Dv NULL
+if
+.Fa si_code
+is not a known signal code.
+.Sh SEE ALSO
+.Xr sysdecode_sigbus_code 3 ,
+.Xr sysdecode_sigchld_code 3 ,
+.Xr sysdecode_sigfpe_code 3 ,
+.Xr sysdecode_sigill_code 3 ,
+.Xr sysdecode_sigsegv_code 3 ,
+.Xr sysdecode_sigtrap_code 3
diff --git a/lib/libsysdecode/sysdecode_socket_protocol.3 b/lib/libsysdecode/sysdecode_socket_protocol.3
new file mode 100644
index 000000000000..bf5f10bb3d7d
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_socket_protocol.3
@@ -0,0 +1,49 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd May 25, 2017
+.Dt sysdecode_socket_protocol 3
+.Os
+.Sh NAME
+.Nm sysdecode_socket_protocol
+.Nd lookup name of socket protocol
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft const char *
+.Fn sysdecode_socket_protocol "int domain" "int protocol"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_socket_protocol
+function returns a text description of the protocol passed in the
+.Fa protocol
+argument to
+.Xr socket 2 .
+.Fn sysdecode_socket_protocol
+takes the
+.Fa protocol
+as well as the
+.Fa domain
+to uniquely identify the protocol.
diff --git a/lib/libsysdecode/sysdecode_sockopt_name.3 b/lib/libsysdecode/sysdecode_sockopt_name.3
new file mode 100644
index 000000000000..09535ac3d860
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_sockopt_name.3
@@ -0,0 +1,56 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd October 17, 2016
+.Dt sysdecode_sockopt_name 3
+.Os
+.Sh NAME
+.Nm sysdecode_sockopt_name
+.Nd lookup name of socket option
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft const char *
+.Fn sysdecode_sockopt_name "int level" "int optname"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_sockopt_name
+function returns a text description of the socket option name passed in the
+.Fa optname
+argument to
+.Xr getsockopt 2 .
+.Fn sysdecode_sockopt_name
+takes the socket option
+.Fa level
+as well as the option name to uniquely identify the option.
+.Sh SEE ALSO
+.Xr sysdecode_sockopt_level 3
+.Sh BUGS
+Socket option levels and names are protocol-specific.
+Both
+.Fn sysdecode_sockopt_level
+and
+.Fn sysdecode_sockopt_name
+should possibly accept the protocol family as an additional argument.
diff --git a/lib/libsysdecode/sysdecode_syscallname.3 b/lib/libsysdecode/sysdecode_syscallname.3
new file mode 100644
index 000000000000..8ba88fd3c43e
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_syscallname.3
@@ -0,0 +1,66 @@
+.\"
+.\" Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd October 17, 2016
+.Dt sysdecode_syscallname 3
+.Os
+.Sh NAME
+.Nm sysdecode_syscallname
+.Nd lookup name of system calls
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft const char *
+.Fn sysdecode_syscallname "enum sysdecode_abi abi" "unsigned int code"
+.Sh DESCRIPTION
+This function returns a pointer to the name of a system call identified by
+.Fa code
+for the process ABI
+.Fa abi .
+If
+.Fa code
+specifies an unknown system call or
+.Fa abi
+is an unsupported ABI,
+.Nm
+returns
+.Dv NULL .
+.Pp
+For the list of supported ABIs,
+see
+.Xr sysdecode 3 .
+.Sh RETURN VALUES
+The
+.Nm
+function returns a pointer to a string on success or
+.Dv NULL
+if either
+.Fa code
+or
+.Fa ABI
+is invalid .
+.Sh SEE ALSO
+.Xr sysdecode 3 ,
+.Xr sysdecode_abi_to_freebsd_errno 3
diff --git a/lib/libsysdecode/sysdecode_utrace.3 b/lib/libsysdecode/sysdecode_utrace.3
new file mode 100644
index 000000000000..859f561324d8
--- /dev/null
+++ b/lib/libsysdecode/sysdecode_utrace.3
@@ -0,0 +1,71 @@
+.\"
+.\" Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd November 24, 2017
+.Dt sysdecode_utrace 3
+.Os
+.Sh NAME
+.Nm sysdecode_utrace
+.Nd produce text description of a utrace record
+.Sh LIBRARY
+.Lb libsysdecode
+.Sh SYNOPSIS
+.In sysdecode.h
+.Ft int
+.Fn sysdecode_utrace "FILE *fp" "void *buf" "size_t len" "int decimal"
+.Sh DESCRIPTION
+The
+.Fn sysdecode_utrace
+function outputs a textual representation of a
+.Xr utrace 2
+record identified by
+.Fa buf
+and
+.Fa len
+to the output stream
+.Fa fp .
+.Pp
+The function only outputs a representation for certain types of records.
+If a record is recognized,
+the function outputs the description and returns a non-zero value.
+If the record is not recognized,
+the function does not output anything and returns zero.
+The
+.Fn sysdecode_utrace
+function currently recognizes
+.Xr utrace 2
+records generated by
+.Xr malloc 3
+and
+.Xr rtld 1 .
+.Sh RETURN VALUES
+The
+.Fn sysdecode_utrace
+function returns a non-zero value if it recognizes a
+.Xr utrace 2
+record;
+otherwise it returns zero.
+.Sh SEE ALSO
+.Xr utrace 2 ,
+.Xr sysdecode 3
diff --git a/lib/libsysdecode/tests/Makefile b/lib/libsysdecode/tests/Makefile
new file mode 100644
index 000000000000..3d75b9b32ba7
--- /dev/null
+++ b/lib/libsysdecode/tests/Makefile
@@ -0,0 +1,5 @@
+ATF_TESTS_C+= sysdecode_test
+
+LIBADD= sysdecode
+
+.include <bsd.test.mk>
diff --git a/lib/libsysdecode/tests/sysdecode_test.c b/lib/libsysdecode/tests/sysdecode_test.c
new file mode 100644
index 000000000000..fa14debc443c
--- /dev/null
+++ b/lib/libsysdecode/tests/sysdecode_test.c
@@ -0,0 +1,152 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 The FreeBSD Foundation
+ *
+ * This software was developed by Mark Johnston under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/capsicum.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+#include <sysdecode.h>
+
+/*
+ * Take a comma-separated list of capability rights and verify that all rights
+ * are present in the specified table, and that all rights in the table are
+ * present in the list.
+ */
+static void
+check_sysdecode_cap_rights(FILE *fp, char **bufp, size_t *szp,
+ cap_rights_t *rightsp, const char *tab[])
+{
+ const char *next, *tok;
+ char *buf;
+ int i;
+
+ sysdecode_cap_rights(fp, rightsp);
+
+ ATF_REQUIRE(fflush(fp) == 0);
+ (*bufp)[*szp] = '\0';
+
+ buf = strdup(*bufp);
+ for (tok = buf; (next = strsep(&buf, ",")), tok != NULL; tok = next) {
+ for (i = 0; tab[i] != NULL; i++) {
+ if (strcmp(tok, tab[i]) == 0)
+ break;
+ }
+ ATF_REQUIRE_MSG(tab[i] != NULL,
+ "did not find '%s' in table", tok);
+ }
+ free(buf);
+
+ for (i = 0; tab[i] != NULL; i++) {
+ buf = strdup(*bufp);
+ for (tok = buf; (next = strsep(&buf, ",")), tok != NULL;
+ tok = next) {
+ if (strcmp(tok, tab[i]) == 0)
+ break;
+ }
+ free(buf);
+ ATF_REQUIRE_MSG(tok != NULL,
+ "did not find '%s' in output stream", tab[i]);
+ }
+
+ ATF_REQUIRE(fseek(fp, 0, SEEK_SET) == 0);
+}
+
+/*
+ * Regression tests for sysdecode_cap_rights(3).
+ */
+ATF_TC_WITHOUT_HEAD(cap_rights);
+ATF_TC_BODY(cap_rights, tc)
+{
+ char *buf;
+ FILE *fp;
+ size_t sz;
+ cap_rights_t rights;
+
+ fp = open_memstream(&buf, &sz);
+ ATF_REQUIRE(fp != NULL);
+
+ /*
+ * libsysdecode emits a pseudo-right, CAP_NONE, when no rights are
+ * present.
+ */
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ cap_rights_init(&rights),
+ (const char *[]){ "CAP_NONE", NULL, });
+
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ cap_rights_init(&rights, CAP_READ, CAP_SEEK),
+ (const char *[]){ "CAP_PREAD", NULL, });
+
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ cap_rights_init(&rights, CAP_READ, CAP_MMAP, CAP_SEEK_TELL),
+ (const char *[]){ "CAP_READ", "CAP_MMAP", "CAP_SEEK_TELL", NULL, });
+
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ cap_rights_init(&rights, CAP_MMAP, CAP_READ, CAP_WRITE, CAP_SEEK),
+ (const char *[]){ "CAP_MMAP_RW", NULL, });
+
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ cap_rights_init(&rights, CAP_READ, CAP_MMAP_X),
+ (const char *[]){ "CAP_MMAP_RX", NULL, });
+
+ /* Aliases map back to the main definition. */
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ cap_rights_init(&rights, CAP_RECV, CAP_SEND),
+ (const char *[]){ "CAP_READ", "CAP_WRITE", NULL, });
+
+ /* This set straddles both indices. */
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ cap_rights_init(&rights, CAP_READ, CAP_KQUEUE),
+ (const char *[]){ "CAP_READ", "CAP_KQUEUE", NULL, });
+
+ /* Create a rights set with an unnamed flag. */
+ cap_rights_init(&rights, CAP_SEEK);
+ cap_rights_clear(&rights, CAP_SEEK_TELL);
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ &rights,
+ (const char *[]){ "CAP_NONE", "unknown rights", NULL, });
+
+ cap_rights_init(&rights, CAP_SEEK, CAP_KQUEUE_CHANGE);
+ cap_rights_clear(&rights, CAP_SEEK_TELL);
+ check_sysdecode_cap_rights(fp, &buf, &sz,
+ &rights,
+ (const char *[]){ "CAP_KQUEUE_CHANGE", "unknown rights", NULL, });
+
+ ATF_REQUIRE(fclose(fp) == 0);
+ free(buf);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, cap_rights);
+
+ return (atf_no_error());
+}
diff --git a/lib/libsysdecode/utrace.c b/lib/libsysdecode/utrace.c
new file mode 100644
index 000000000000..67ba86bfbf7b
--- /dev/null
+++ b/lib/libsysdecode/utrace.c
@@ -0,0 +1,211 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <dlfcn.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sysdecode.h>
+#include "rtld_utrace.h"
+
+#ifdef __LP64__
+struct utrace_rtld32 {
+ char sig[4];
+ int event;
+ uint32_t handle;
+ uint32_t mapbase;
+ uint32_t mapsize;
+ int refcnt;
+ char name[MAXPATHLEN];
+};
+#endif
+
+static int
+print_utrace_rtld(FILE *fp, void *p)
+{
+ struct utrace_rtld *ut = p;
+ void *parent;
+ int mode;
+
+ switch (ut->event) {
+ case UTRACE_DLOPEN_START:
+ mode = ut->refcnt;
+ fprintf(fp, "dlopen(%s, ", ut->name);
+ switch (mode & RTLD_MODEMASK) {
+ case RTLD_NOW:
+ fprintf(fp, "RTLD_NOW");
+ break;
+ case RTLD_LAZY:
+ fprintf(fp, "RTLD_LAZY");
+ break;
+ default:
+ fprintf(fp, "%#x", mode & RTLD_MODEMASK);
+ }
+ if (mode & RTLD_GLOBAL)
+ fprintf(fp, " | RTLD_GLOBAL");
+ if (mode & RTLD_TRACE)
+ fprintf(fp, " | RTLD_TRACE");
+ if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
+ fprintf(fp, " | %#x", mode &
+ ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
+ fprintf(fp, ")");
+ break;
+ case UTRACE_DLOPEN_STOP:
+ fprintf(fp, "%p = dlopen(%s) ref %d", ut->handle, ut->name,
+ ut->refcnt);
+ break;
+ case UTRACE_DLCLOSE_START:
+ fprintf(fp, "dlclose(%p) (%s, %d)", ut->handle, ut->name,
+ ut->refcnt);
+ break;
+ case UTRACE_DLCLOSE_STOP:
+ fprintf(fp, "dlclose(%p) finished", ut->handle);
+ break;
+ case UTRACE_LOAD_OBJECT:
+ fprintf(fp, "RTLD: loaded %p @ %p - %p (%s)", ut->handle,
+ ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
+ ut->name);
+ break;
+ case UTRACE_UNLOAD_OBJECT:
+ fprintf(fp, "RTLD: unloaded %p @ %p - %p (%s)", ut->handle,
+ ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
+ ut->name);
+ break;
+ case UTRACE_ADD_RUNDEP:
+ parent = ut->mapbase;
+ fprintf(fp, "RTLD: %p now depends on %p (%s, %d)", parent,
+ ut->handle, ut->name, ut->refcnt);
+ break;
+ case UTRACE_PRELOAD_FINISHED:
+ fprintf(fp, "RTLD: LD_PRELOAD finished");
+ break;
+ case UTRACE_INIT_CALL:
+ fprintf(fp, "RTLD: init %p for %p (%s)", ut->mapbase, ut->handle,
+ ut->name);
+ break;
+ case UTRACE_FINI_CALL:
+ fprintf(fp, "RTLD: fini %p for %p (%s)", ut->mapbase, ut->handle,
+ ut->name);
+ break;
+ case UTRACE_DLSYM_START:
+ fprintf(fp, "RTLD: dlsym(%p, %s)", ut->handle, ut->name);
+ break;
+ case UTRACE_DLSYM_STOP:
+ fprintf(fp, "RTLD: %p = dlsym(%p, %s)", ut->mapbase, ut->handle,
+ ut->name);
+ break;
+ case UTRACE_RTLD_ERROR:
+ fprintf(fp, "RTLD: error: %s\n", ut->name);
+ break;
+
+ default:
+ return (0);
+ }
+ return (1);
+}
+
+struct utrace_malloc {
+ void *p;
+ size_t s;
+ void *r;
+};
+
+#ifdef __LP64__
+struct utrace_malloc32 {
+ uint32_t p;
+ uint32_t s;
+ uint32_t r;
+};
+#endif
+
+static void
+print_utrace_malloc(FILE *fp, void *p)
+{
+ struct utrace_malloc *ut = p;
+
+ if (ut->p == (void *)(intptr_t)(-1))
+ fprintf(fp, "malloc_init()");
+ else if (ut->s == 0)
+ fprintf(fp, "free(%p)", ut->p);
+ else if (ut->p == NULL)
+ fprintf(fp, "%p = malloc(%zu)", ut->r, ut->s);
+ else
+ fprintf(fp, "%p = realloc(%p, %zu)", ut->r, ut->p, ut->s);
+}
+
+int
+sysdecode_utrace(FILE *fp, void *p, size_t len)
+{
+#ifdef __LP64__
+ struct utrace_rtld ur;
+ struct utrace_rtld32 *pr;
+ struct utrace_malloc um;
+ struct utrace_malloc32 *pm;
+#endif
+ static const char rtld_utrace_sig[RTLD_UTRACE_SIG_SZ] = RTLD_UTRACE_SIG;
+
+ if (len == sizeof(struct utrace_rtld) && bcmp(p, rtld_utrace_sig,
+ sizeof(rtld_utrace_sig)) == 0)
+ return (print_utrace_rtld(fp, p));
+
+ if (len == sizeof(struct utrace_malloc)) {
+ print_utrace_malloc(fp, p);
+ return (1);
+ }
+
+#ifdef __LP64__
+ if (len == sizeof(struct utrace_rtld32) && bcmp(p, rtld_utrace_sig,
+ sizeof(rtld_utrace_sig)) == 0) {
+ pr = p;
+ memset(&ur, 0, sizeof(ur));
+ memcpy(ur.sig, pr->sig, sizeof(ur.sig));
+ ur.event = pr->event;
+ ur.handle = (void *)(uintptr_t)pr->handle;
+ ur.mapbase = (void *)(uintptr_t)pr->mapbase;
+ ur.mapsize = pr->mapsize;
+ ur.refcnt = pr->refcnt;
+ memcpy(ur.name, pr->name, sizeof(ur.name));
+ return (print_utrace_rtld(fp, &ur));
+ }
+
+ if (len == sizeof(struct utrace_malloc32)) {
+ pm = p;
+ memset(&um, 0, sizeof(um));
+ um.p = pm->p == (uint32_t)-1 ? (void *)(intptr_t)-1 :
+ (void *)(uintptr_t)pm->p;
+ um.s = pm->s;
+ um.r = (void *)(uintptr_t)pm->r;
+ print_utrace_malloc(fp, &um);
+ return (1);
+ }
+#endif
+
+ return (0);
+}