Author: jhb
Date: Mon Oct 17 22:37:07 2016
New Revision: 307538
URL: https://svnweb.freebsd.org/changeset/base/307538

Log:
  Move mksubr from kdump into libsysdecode.
  
  Restructure this script so that it generates a header of tables instead
  of a source file.  The tables are included in a flags.c source file which
  provides functions to decode various system call arguments.
  
  For functions that decode an enumeration, the function returns a pointer
  to a string for known values and NULL for unknown values.
  
  For functions that do more complex decoding (typically of a bitmask), the
  function accepts a pointer to a FILE object (open_memstream() can be used
  as a string builder) to which decoded values are written.  If the
  function operates on a bitmask, the function returns true if any bits
  were decoded or false if the entire value was valid.  Additionally, the
  third argument accepts a pointer to a value to which any undecoded bits
  are stored.  This pointer can be NULL if the caller doesn't care about
  remaining bits.
  
  Convert kdump over to using decoder functions from libsysdecode instead of
  mksubr.  truss also uses decoders from libsysdecode instead of private
  lookup tables, though lookup tables for objects not decoded by kdump remain
  in truss for now.  Eventually most of these tables should move into
  libsysdecode as the automated table generation approach from mksubr is
  less stale than the static tables in truss.
  
  Some changes have been made to truss and kdump output:
  - The flags passed to open() are now properly decoded in that one of
    O_RDONLY, O_RDWR, O_WRONLY, or O_EXEC is always included in a decoded
    mask.
  - Optional arguments to open(), openat(), and fcntl() are only printed
    in kdump if they exist (e.g. the mode is only printed for open() if
    O_CREAT is set in the flags).
  - Print argument to F_GETLK/SETLK/SETLKW in kdump as a pointer, not int.
  - Include all procctl() commands.
  - Correctly decode pipe2() flags in truss by not assuming full
    open()-like flags with O_RDONLY, etc.
  - Decode file flags passed to *chflags() as file flags (UF_* and SF_*)
    rather than as a file mode.
  - Fix decoding of quotactl() commands by splitting out the two command
    components instead of assuming the raw command value matches the
    primary command component.
  
  In addition, truss and kdump now build without triggering any warnings.
  All of the sysdecode manpages now include the required headers in the
  synopsis.
  
  Reviewed by:  kib (several older versions), wblock (manpages)
  MFC after:    2 months
  Differential Revision:        https://reviews.freebsd.org/D7847

Added:
  head/lib/libsysdecode/flags.c
     - copied, changed from r307534, head/usr.bin/kdump/mksubr
  head/lib/libsysdecode/mktables
     - copied, changed from r307534, head/usr.bin/kdump/mksubr
  head/lib/libsysdecode/signal.c   (contents, props changed)
  head/lib/libsysdecode/sysdecode_cap_rights.3   (contents, props changed)
  head/lib/libsysdecode/sysdecode_enum.3   (contents, props changed)
  head/lib/libsysdecode/sysdecode_fcntl_arg.3   (contents, props changed)
  head/lib/libsysdecode/sysdecode_mask.3   (contents, props changed)
  head/lib/libsysdecode/sysdecode_quotactl_cmd.3   (contents, props changed)
  head/lib/libsysdecode/sysdecode_sigcode.3   (contents, props changed)
  head/lib/libsysdecode/sysdecode_sockopt_name.3   (contents, props changed)
Deleted:
  head/usr.bin/kdump/mksubr
Modified:
  head/lib/libsysdecode/Makefile
  head/lib/libsysdecode/errno.c
  head/lib/libsysdecode/mkioctls
  head/lib/libsysdecode/syscallnames.c
  head/lib/libsysdecode/sysdecode.3
  head/lib/libsysdecode/sysdecode.h
  head/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3
  head/lib/libsysdecode/sysdecode_ioctlname.3
  head/lib/libsysdecode/sysdecode_syscallnames.3
  head/lib/libsysdecode/sysdecode_utrace.3
  head/lib/libsysdecode/utrace.c
  head/usr.bin/kdump/Makefile
  head/usr.bin/kdump/kdump.c
  head/usr.bin/truss/Makefile
  head/usr.bin/truss/aarch64-cloudabi64.c
  head/usr.bin/truss/aarch64-freebsd.c
  head/usr.bin/truss/amd64-cloudabi64.c
  head/usr.bin/truss/amd64-freebsd.c
  head/usr.bin/truss/amd64-freebsd32.c
  head/usr.bin/truss/amd64-linux.c
  head/usr.bin/truss/amd64-linux32.c
  head/usr.bin/truss/arm-freebsd.c
  head/usr.bin/truss/extern.h
  head/usr.bin/truss/i386-freebsd.c
  head/usr.bin/truss/i386-linux.c
  head/usr.bin/truss/main.c
  head/usr.bin/truss/mips-freebsd.c
  head/usr.bin/truss/powerpc-freebsd.c
  head/usr.bin/truss/powerpc64-freebsd.c
  head/usr.bin/truss/powerpc64-freebsd32.c
  head/usr.bin/truss/setup.c
  head/usr.bin/truss/sparc64-freebsd.c
  head/usr.bin/truss/syscall.h
  head/usr.bin/truss/syscalls.c

Modified: head/lib/libsysdecode/Makefile
==============================================================================
--- head/lib/libsysdecode/Makefile      Mon Oct 17 22:36:37 2016        
(r307537)
+++ head/lib/libsysdecode/Makefile      Mon Oct 17 22:37:07 2016        
(r307538)
@@ -5,20 +5,94 @@
 PACKAGE=lib${LIB}
 LIB=   sysdecode
 
-SRCS=  errno.c ioctl.c syscallnames.c utrace.c
+SRCS=  errno.c flags.c ioctl.c signal.c syscallnames.c utrace.c
 INCS=  sysdecode.h
 
+CFLAGS+= -I${.OBJDIR}
 CFLAGS+= -I${.CURDIR}/../../sys
 CFLAGS+= -I${.CURDIR}/../../libexec/rtld-elf
 
-MAN+=  sysdecode.3 \
+MAN=   sysdecode.3 \
        sysdecode_abi_to_freebsd_errno.3 \
+       sysdecode_cap_rights.3 \
+       sysdecode_enum.3 \
+       sysdecode_fcntl_arg.3 \
        sysdecode_ioctlname.3 \
+       sysdecode_mask.3 \
+       sysdecode_quotactl_cmd.3 \
+       sysdecode_sigcode.3 \
+       sysdecode_sockopt_name.3 \
        sysdecode_syscallnames.3 \
        sysdecode_utrace.3
-MLINKS+= sysdecode_abi_to_freebsd_errno.3 sysdecode_freebsd_to_abi_errno.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_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_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_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_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_mask.3 sysdecode_accessmode.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_getfsstat_flags.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_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_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
+CLEANFILES= ioctl.c tables.h
 
 .if defined(COMPAT_32BIT)
 CPP+=  -m32
@@ -36,10 +110,13 @@ CFLAGS.gcc.ioctl.c+= -Wno-unused
 
 CFLAGS.gcc+=   ${CFLAGS.gcc.${.IMPSRC}}
 
+tables.h: mktables
+       sh ${.CURDIR}/mktables ${DESTDIR}${INCLUDEDIR} > ${.TARGET}
+
 ioctl.c: mkioctls
        env MACHINE=${MACHINE} CPP="${CPP}" \
                /bin/sh ${.CURDIR}/mkioctls ${DESTDIR}${INCLUDEDIR} > ${.TARGET}
 
-beforedepend: ioctl.c
+beforedepend: ioctl.c tables.h
 
 .include <bsd.lib.mk>

Modified: head/lib/libsysdecode/errno.c
==============================================================================
--- head/lib/libsysdecode/errno.c       Mon Oct 17 22:36:37 2016        
(r307537)
+++ head/lib/libsysdecode/errno.c       Mon Oct 17 22:37:07 2016        
(r307538)
@@ -28,8 +28,11 @@
 __FBSDID("$FreeBSD$");
 
 #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>
 

Copied and modified: head/lib/libsysdecode/flags.c (from r307534, 
head/usr.bin/kdump/mksubr)
==============================================================================
--- head/usr.bin/kdump/mksubr   Mon Oct 17 21:49:54 2016        (r307534, copy 
source)
+++ head/lib/libsysdecode/flags.c       Mon Oct 17 22:37:07 2016        
(r307538)
@@ -1,198 +1,92 @@
-#!/bin/sh
-#
-# Copyright (c) 2006 "David Kirchner" <d...@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.
-#
-# $FreeBSD$
-#
-# Generates kdump_subr.c
-# mkioctls is a special-purpose script, and works fine as it is
-# now, so it remains independent. The idea behind how it generates
-# its list was heavily borrowed here.
-#
-# Some functions here are automatically generated. This can mean
-# the user will see unusual kdump output or errors while building
-# if the underlying .h files are changed significantly.
-#
-# Key:
-# AUTO: Completely auto-generated with either the "or" or the "switch"
-# method.
-# AUTO - Special: Generated automatically, but with some extra commands
-# that the auto_*_type() functions are inappropriate for.
-# MANUAL: Manually entered and must therefore be manually updated.
-
-set -e
-
-LC_ALL=C; export LC_ALL
-
-if [ -z "$1" ]
-then
-       echo "usage: sh $0 include-dir"
-       exit 1
-fi
-include_dir=$1
-
-#
-# Automatically generates a C function that will print out the
-# numeric input as a pipe-delimited string of the appropriate
-# #define keys. ex:
-# S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
-# The XOR is necessary to prevent including the "0"-value in every
-# line.
-#
-auto_or_type () {
-       local name grep file
-       name=$1
-       grep=$2
-       file=$3
-
-       cat <<_EOF_
-/* AUTO */
-void
-$name(intmax_t arg)
-{
-       int or = 0;
-       printf("%#jx<", (uintmax_t)arg);
-_EOF_
-       egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
-               $include_dir/$file | \
-       awk '{ for (i = 1; i <= NF; i++) \
-               if ($i ~ /define/) \
-                       break; \
-               ++i; \
-               printf "\tif (!((arg > 0) ^ ((%s) > 0)))\n\t\tif_print_or(arg, 
%s, or);\n", $i, $i }'
-cat <<_EOF_
-       printf(">");
-       if (or == 0)
-               printf("<invalid>%jd", arg);
-}
-
-_EOF_
-}
-
-#
-# Automatically generates a C function used when the argument
-# maps to a single, specific #definition
-#
-auto_switch_type () {
-       local name grep file
-       name=$1
-       grep=$2
-       file=$3
-
-       cat <<_EOF_
-/* AUTO */
-void
-$name(intmax_t arg)
-{
-       switch (arg) {
-_EOF_
-       egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
-               $include_dir/$file | \
-       awk '{ for (i = 1; i <= NF; i++) \
-               if ($i ~ /define/) \
-                       break; \
-               ++i; \
-               printf "\tcase %s:\n\t\tprintf(\"%s\");\n\t\tbreak;\n", $i, $i 
}'
-cat <<_EOF_
-       default: /* Should not reach */
-               printf("<invalid=%jd>", arg);
-       }
-}
-
-_EOF_
-}
-
-#
-# Automatically generates a C function used when the argument
-# maps to a #definition
-#
-auto_if_type () {
-       local name grep file
-       name=$1
-       grep=$2
-       file=$3
-
-       cat <<_EOF_
-/* AUTO */
-void
-$name(intmax_t arg)
-{
-_EOF_
-       egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
-               $include_dir/$file | \
-       awk '{ printf "\t"; \
-               if (NR > 1) \
-                       printf "else " ; \
-               printf "if (arg == %s) \n\t\tprintf(\"%s\");\n", $2, $2 }'
-cat <<_EOF_
-       else /* Should not reach */
-               printf("<invalid=%jd>", arg);
-}
+/*
+ * Copyright (c) 2006 "David Kirchner" <d...@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.
+ */
 
-_EOF_
-}
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-# C start
+#define L2CAP_SOCKET_CHECKED
 
-cat <<_EOF_
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#include <sys/unistd.h>
+#include <sys/types.h>
+#include <sys/acl.h>
+#include <sys/capsicum.h>
+#include <sys/extattr.h>
+#include <sys/linker.h>
 #include <sys/mman.h>
-#include <sys/wait.h>
-#define _KERNEL
-#include <sys/socket.h>
-#undef _KERNEL
-#include <netinet/in.h>
-#include <sys/param.h>
 #include <sys/mount.h>
 #include <sys/procctl.h>
 #include <sys/ptrace.h>
-#include <sys/resource.h>
 #include <sys/reboot.h>
-#include <sched.h>
-#include <sys/linker.h>
-#define _KERNEL
-#include <sys/thr.h>
-#undef _KERNEL
-#include <sys/extattr.h>
-#include <sys/acl.h>
-#include <aio.h>
-#include <sys/sem.h>
-#include <sys/ipc.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 <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
 #include <nfsserver/nfs.h>
 #include <ufs/ufs/quota.h>
-#include <sys/capsicum.h>
-#include <vm/vm.h>
 #include <vm/vm_param.h>
-
-#include "kdump_subr.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>
+
+/*
+ * 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;
+};
+
+#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
 
 /*
  * These are simple support macros. print_or utilizes a variable
@@ -201,559 +95,888 @@ cat <<_EOF_
  * simply handles the necessary "if" statement used in many lines
  * of this file.
  */
-#define print_or(str,orflag) do {                  \\
-       if (orflag) putchar('|'); else orflag = 1; \\
-       printf (str); }                            \\
+#define print_or(fp,str,orflag) do {                     \
+       if (orflag) fputc(fp, '|'); else orflag = true;  \
+       fprintf(fp, str); }                              \
        while (0)
-#define if_print_or(i,flag,orflag) do {            \\
-       if ((i & flag) == flag)                    \\
-       print_or(#flag,orflag); }                  \\
+#define if_print_or(fp,i,flag,orflag) do {         \
+       if ((i & flag) == flag)                    \
+       print_or(fp,#flag,orflag); }               \
        while (0)
 
-/* MANUAL */
-void
-atfdname(int fd, int decimal)
+static const char *
+lookup_value(struct name_table *table, uintmax_t val)
 {
-       if (fd == AT_FDCWD)
-               printf("AT_FDCWD");
-       else if (decimal)
-               printf("%d", fd);
-       else
-               printf("%#x", fd);
+
+       for (; table->str != NULL; table++)
+               if (table->val == val)
+                       return (table->str);
+       return (NULL);
 }
 
-/* MANUAL */
-extern char *signames[]; /* from kdump.c */
-void
-signame(int sig)
+/*
+ * 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.
+ */
+static 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.
+ */
+static bool
+print_mask_int(FILE *fp, struct name_table *table, int ival, int *rem)
 {
-       if (sig > 0 && sig < NSIG)
-               printf("SIG%s",signames[sig]);
-       else
-               printf("SIG %d", sig);
+       uintmax_t val;
+       bool printed;
+
+       printed = false;
+       val = (unsigned)ival;
+       print_mask_part(fp, table, &val, &printed);
+       if (rem != NULL)
+               *rem = val;
+       return (printed);
 }
 
-/* MANUAL */
-void
-semctlname(int cmd)
+/*
+ * Used for a mask of optional flags where a value of 0 is valid.
+ */
+static bool
+print_mask_0(FILE *fp, struct name_table *table, int val, int *rem)
 {
-       switch (cmd) {
-       case GETNCNT:
-               printf("GETNCNT");
-               break;
-       case GETPID:
-               printf("GETPID");
-               break;
-       case GETVAL:
-               printf("GETVAL");
-               break;
-       case GETALL:
-               printf("GETALL");
-               break;
-       case GETZCNT:
-               printf("GETZCNT");
-               break;
-       case SETVAL:
-               printf("SETVAL");
-               break;
-       case SETALL:
-               printf("SETALL");
+
+       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.
+ */
+static 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);
+}
+
+static void
+print_integer(FILE *fp, int val, int base)
+{
+
+       switch (base) {
+       case 8:
+               fprintf(fp, "0%o", val);
                break;
-       case IPC_RMID:
-               printf("IPC_RMID");
+       case 10:
+               fprintf(fp, "%d", val);
                break;
-       case IPC_SET:
-               printf("IPC_SET");
+       case 16:
+               fprintf(fp, "0x%x", val);
                break;
-       case IPC_STAT:
-               printf("IPC_STAT");
+       default:
+               abort2("bad base", 0, NULL);
                break;
-       default: /* Should not reach */
-               printf("<invalid=%d>", cmd);
        }
 }
 
-/* MANUAL */
-void
-shmctlname(int cmd)
+static bool
+print_value(FILE *fp, struct name_table *table, uintmax_t val)
 {
-       switch (cmd) {
-       case IPC_RMID:
-               printf("IPC_RMID");
-               break;
-       case IPC_SET:
-               printf("IPC_SET");
-               break;
-       case IPC_STAT:
-               printf("IPC_STAT");
-               break;
-       default: /* Should not reach */
-               printf("<invalid=%d>", cmd);
+       const char *str;
+
+       str = lookup_value(table, val);
+       if (str != NULL) {
+               fputs(str, fp);
+               return (true);
        }
+       return (false);
 }
 
-/* MANUAL */
-void
-semgetname(int flag)
+const char *
+sysdecode_atfd(int fd)
+{
+
+       if (fd == AT_FDCWD)
+               return ("AT_FDCWD");
+       return (NULL);
+}
+
+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)
 {
-       int or = 0;
-       if_print_or(flag, IPC_CREAT, or);
-       if_print_or(flag, IPC_EXCL, or);
-       if_print_or(flag, SEM_R, or);
-       if_print_or(flag, SEM_A, or);
-       if_print_or(flag, (SEM_R>>3), or);
-       if_print_or(flag, (SEM_A>>3), or);
-       if_print_or(flag, (SEM_R>>6), or);
-       if_print_or(flag, (SEM_A>>6), or);
+
+       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));
 }
 
 /*
- * MANUAL
- *
- * Only used by SYS_open. Unless O_CREAT is set in flags, the
- * mode argument is unused (and often bogus and misleading).
+ * [g|s]etsockopt's level argument can either be SOL_SOCKET or a
+ * protocol-specific value.
  */
-void
-flagsandmodename(int flags, int mode, int decimal)
+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_NONBLOCK) XEND
+};
+
+bool
+sysdecode_socket_type(FILE *fp, int type, int *rem)
 {
-       flagsname(flags);
-       putchar(',');
-       if ((flags & O_CREAT) == O_CREAT) {
-               modename (mode);
+       const char *str;
+       uintmax_t val;
+       bool printed;
+
+       str = lookup_value(socktype, type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK));
+       if (str != NULL) {
+               fputs(str, fp);
+               *rem = 0;
+               printed = true;
        } else {
-               if (decimal) {
-                       printf("<unused>%d", mode);
-               } else {
-                       printf("<unused>%#x", (unsigned int)mode);
-               }
+               *rem = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
+               printed = false;
        }
+       val = type & (SOCK_CLOEXEC | SOCK_NONBLOCK);
+       print_mask_part(fp, sockflags, &val, &printed);
+       return (printed);
 }
 
-/* MANUAL */
-void
-idtypename(idtype_t idtype, int decimal)
+bool
+sysdecode_access_mode(FILE *fp, int mode, int *rem)
 {
-       switch(idtype) {
-       case P_PID:
-               printf("P_PID");
-               break;
-       case P_PPID:
-               printf("P_PPID");
-               break;
-       case P_PGID:
-               printf("P_PGID");
-               break;
-       case P_SID:
-               printf("P_SID");
-               break;
-       case P_CID:
-               printf("P_CID");
-               break;
-       case P_UID:
-               printf("P_UID");
-               break;
-       case P_GID:
-               printf("P_GID");
-               break;
-       case P_ALL:
-               printf("P_ALL");
-               break;
-       case P_LWPID:
-               printf("P_LWPID");
-               break;
-       case P_TASKID:
-               printf("P_TASKID");
-               break;
-       case P_PROJID:
-               printf("P_PROJID");
-               break;
-       case P_POOLID:
-               printf("P_POOLID");
-               break;
-       case P_JAILID:
-               printf("P_JAILID");
-               break;
-       case P_CTID:
-               printf("P_CTID");
+
+       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));
+}
+
+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 P_CPUID:
-               printf("P_CPUID");
+       case O_WRONLY:
+               fputs("O_WRONLY", fp);
+               printed = true;
+               mode = 0;
                break;
-       case P_PSETID:
-               printf("P_PSETID");
+       case O_RDWR:
+               fputs("O_RDWR", fp);
+               printed = true;
+               mode = 0;
                break;
        default:
-               if (decimal) {
-                       printf("%d", idtype);
-               } else {
-                       printf("%#x", idtype);
-               }
+               printed = false;
        }
+       val = (unsigned)flags;
+       print_mask_part(fp, openflags, &val, &printed);
+       if (rem != NULL)
+               *rem = val | mode;
+       return (printed);
 }
 
-/*
- * MANUAL
- *
- * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
- * referring to a line in /etc/protocols . It might be appropriate
- * to use getprotoent(3) here.
- */
-void
-sockoptlevelname(int level, int decimal)
+bool
+sysdecode_fcntl_fileflags(FILE *fp, int flags, int *rem)
 {
-       if (level == SOL_SOCKET) {
-               printf("SOL_SOCKET");
-       } else {
-               if (decimal) {
-                       printf("%d", level);
-               } else {
-                       printf("%#x", (unsigned int)level);
-               }
+       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);
 }
 
-/*
- * MANUAL
- *
- * Used for page fault type.  Cannot use auto_or_type since the macro
- * values contain a cast.  Also, VM_PROT_NONE has to be handled specially.
- */
-void
-vmprotname (int type)
+bool
+sysdecode_flock_operation(FILE *fp, int operation, int *rem)
 {
-       int     or = 0;
 
-       if (type == VM_PROT_NONE) {
-               (void)printf("VM_PROT_NONE");
-               return;
-       }
-       if_print_or(type, VM_PROT_READ, or);
-       if_print_or(type, VM_PROT_WRITE, or);
-       if_print_or(type, VM_PROT_EXECUTE, or);
-       if_print_or(type, VM_PROT_COPY, or);
+       return (print_mask_int(fp, flockops, operation, rem));
 }
 
-/*
- * MANUAL
- */
-void
-socktypenamewithflags(int type)
+bool
+sysdecode_getfsstat_flags(FILE *fp, int flags, int *rem)
 {
-       if (type & SOCK_CLOEXEC)
-               printf("SOCK_CLOEXEC|"), type &= ~SOCK_CLOEXEC;
-       if (type & SOCK_NONBLOCK)
-               printf("SOCK_NONBLOCK|"), type &= ~SOCK_NONBLOCK;
-       socktypename(type);
-}
-_EOF_
-
-auto_or_type     "accessmodename"      "[A-Z]_OK[[:space:]]+0?x?[0-9A-Fa-f]+"  
       "sys/unistd.h"
-auto_switch_type "acltypename"         "ACL_TYPE_[A-Z4_]+[[:space:]]+0x[0-9]+" 
       "sys/acl.h"
-auto_or_type     "capfcntlname"        "CAP_FCNTL_[A-Z]+[[:space:]]+\(1"       
       "sys/capsicum.h"
-auto_switch_type "extattrctlname"      
"EXTATTR_NAMESPACE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/extattr.h"
-auto_switch_type "fadvisebehavname"    "POSIX_FADV_[A-Z]+[[:space:]]+[0-9]+"   
       "sys/fcntl.h"
-auto_or_type     "flagsname"           "O_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+"    
       "sys/fcntl.h"
-auto_or_type     "flockname"           "LOCK_[A-Z]+[[:space:]]+0x[0-9]+"       
       "sys/fcntl.h"
-auto_or_type     "getfsstatflagsname"  "MNT_[A-Z]+[[:space:]]+[1-9][0-9]*"     
       "sys/mount.h"
-auto_switch_type "kldsymcmdname"       "KLDSYM_[A-Z]+[[:space:]]+[0-9]+"       
       "sys/linker.h"
-auto_switch_type "kldunloadfflagsname" 
"LINKER_UNLOAD_[A-Z]+[[:space:]]+[0-9]+"       "sys/linker.h"
-auto_switch_type "lio_listioname"      "LIO_(NO)?WAIT[[:space:]]+[0-9]+"       
       "aio.h"
-auto_switch_type "madvisebehavname"    "_?MADV_[A-Z]+[[:space:]]+[0-9]+"       
       "sys/mman.h"

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to