diff --git a/lib/libsysdecode/linux.c b/lib/libsysdecode/linux.c index 8a3b88a7bfca..ef015dab6dd8 100644 --- a/lib/libsysdecode/linux.c +++ b/lib/libsysdecode/linux.c @@ -1,207 +1,242 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2022 Dmitry Chagin * * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "support.h" #ifdef __aarch64__ #include #elif __i386__ #include #elif __amd64__ #ifdef COMPAT_32BIT #include #else #include #endif #else #error "Unsupported Linux arch" #endif #include #include #include #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); +} diff --git a/lib/libsysdecode/mklinuxtables b/lib/libsysdecode/mklinuxtables index 734d69fca9cf..bcd6ddb5f618 100644 --- a/lib/libsysdecode/mklinuxtables +++ b/lib/libsysdecode/mklinuxtables @@ -1,112 +1,113 @@ #!/bin/sh # # Copyright (c) 2006 "David Kirchner" . 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 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_timer.h" gen_table "clockflags" "LINUX_TIMER_[A-Z_]+[[:space:]]+0x[0-9]+" "compat/linux/linux_timer.h" gen_table "clockcpuids" "LINUX_CPUCLOCK_[A-Z_]+[[:space:]]+[0-9]+" "compat/linux/linux_timer.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" # 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/sysdecode.h b/lib/libsysdecode/sysdecode.h index ae09077e969e..4ea2989ca185 100644 --- a/lib/libsysdecode/sysdecode.h +++ b/lib/libsysdecode/sysdecode.h @@ -1,152 +1,153 @@ /*- * Copyright (c) 2015 John H. Baldwin * * 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$ */ #ifndef __SYSDECODE_H__ #define __SYSDECODE_H__ #include #include #include enum sysdecode_abi { SYSDECODE_ABI_UNKNOWN = 0, SYSDECODE_ABI_FREEBSD, SYSDECODE_ABI_FREEBSD32, SYSDECODE_ABI_LINUX, SYSDECODE_ABI_LINUX32, SYSDECODE_ABI_CLOUDABI64, SYSDECODE_ABI_CLOUDABI32 }; 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); 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); 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_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__ */