1147476Sdumbbell/*- 2147476Sdumbbell * SPDX-License-Identifier: BSD-2-Clause 3147476Sdumbbell * 4147476Sdumbbell * Copyright (c) 2022 Dmitry Chagin <dchagin@FreeBSD.org> 5230132Suqs * 6147476Sdumbbell * Redistribution and use in source and binary forms, with or without 7147476Sdumbbell * modification, are permitted provided that the following conditions 8147476Sdumbbell * are met: 9147476Sdumbbell * 1. Redistributions of source code must retain the above copyright 10147476Sdumbbell * notice, this list of conditions and the following disclaimer. 11147476Sdumbbell * 2. Redistributions in binary form must reproduce the above copyright 12147476Sdumbbell * notice, this list of conditions and the following disclaimer in the 13147476Sdumbbell * documentation and/or other materials provided with the distribution. 14147476Sdumbbell * 15147476Sdumbbell * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16147476Sdumbbell * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17147476Sdumbbell * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18147476Sdumbbell * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19147476Sdumbbell * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20147476Sdumbbell * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21147476Sdumbbell * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22147476Sdumbbell * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23147476Sdumbbell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24147476Sdumbbell * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25147476Sdumbbell * SUCH DAMAGE. 26147476Sdumbbell */ 27147476Sdumbbell 28147476Sdumbbell#include <sys/types.h> 29147476Sdumbbell#include <sys/proc.h> 30147476Sdumbbell#include <stdbool.h> 31147476Sdumbbell#include <stdio.h> 32147476Sdumbbell#include <sysdecode.h> 33147476Sdumbbell 34147476Sdumbbell#include "support.h" 35147476Sdumbbell 36147476Sdumbbell#ifdef __aarch64__ 37147476Sdumbbell#include <arm64/linux/linux.h> 38147476Sdumbbell#elif __i386__ 39147476Sdumbbell#include <i386/linux/linux.h> 40147476Sdumbbell#elif __amd64__ 41147476Sdumbbell#include <amd64/linux/linux.h> 42147476Sdumbbell#else 43147476Sdumbbell#error "Unsupported Linux arch" 44147476Sdumbbell#endif 45147476Sdumbbell 46147476Sdumbbell#include <compat/linux/linux.h> 47147476Sdumbbell#include <compat/linux/linux_file.h> 48147476Sdumbbell#include <compat/linux/linux_fork.h> 49147476Sdumbbell#include <compat/linux/linux_time.h> 50147476Sdumbbell 51147476Sdumbbell#define X(a,b) { a, #b }, 52147476Sdumbbell#define XEND { 0, NULL } 53147476Sdumbbell 54147476Sdumbbell#define TABLE_START(n) static struct name_table n[] = { 55147476Sdumbbell#define TABLE_ENTRY X 56147476Sdumbbell#define TABLE_END XEND }; 57147476Sdumbbell 58147476Sdumbbell#include "tables_linux.h" 59147476Sdumbbell 60147476Sdumbbell#undef TABLE_START 61147476Sdumbbell#undef TABLE_ENTRY 62147476Sdumbbell#undef TABLE_END 63147476Sdumbbell 64147476Sdumbbellstatic const char *linux_signames[] = { 65147476Sdumbbell [LINUX_SIGHUP] = "SIGHUP", 66147476Sdumbbell [LINUX_SIGINT] = "SIGINT", 67147476Sdumbbell [LINUX_SIGQUIT] = "SIGQUIT", 68147476Sdumbbell [LINUX_SIGILL] = "SIGILL", 69147476Sdumbbell [LINUX_SIGTRAP] = "SIGTRAP", 70147476Sdumbbell [LINUX_SIGABRT] = "SIGABRT", 71147476Sdumbbell [LINUX_SIGBUS] = "SIGBUS", 72147476Sdumbbell [LINUX_SIGFPE] = "SIGFPE", 73147476Sdumbbell [LINUX_SIGKILL] = "SIGKILL", 74147476Sdumbbell [LINUX_SIGUSR1] = "SIGUSR1", 75147476Sdumbbell [LINUX_SIGSEGV] = "SIGSEGV", 76147476Sdumbbell [LINUX_SIGUSR2] = "SIGUSR2", 77147476Sdumbbell [LINUX_SIGPIPE] = "SIGPIPE", 78147476Sdumbbell [LINUX_SIGALRM] = "SIGALRM", 79147476Sdumbbell [LINUX_SIGTERM] = "SIGTERM", 80147476Sdumbbell [LINUX_SIGSTKFLT] = "SIGSTKFLT", 81147476Sdumbbell [LINUX_SIGCHLD] = "SIGCHLD", 82147476Sdumbbell [LINUX_SIGCONT] = "SIGCONT", 83147476Sdumbbell [LINUX_SIGSTOP] = "SIGSTOP", 84147476Sdumbbell [LINUX_SIGTSTP] = "SIGTSTP", 85147476Sdumbbell [LINUX_SIGTTIN] = "SIGTTIN", 86147476Sdumbbell [LINUX_SIGTTOU] = "SIGTTOU", 87147476Sdumbbell [LINUX_SIGURG] = "SIGURG", 88147476Sdumbbell [LINUX_SIGXCPU] = "SIGXCPU", 89147476Sdumbbell [LINUX_SIGXFSZ] = "SIGXFSZ", 90147476Sdumbbell [LINUX_SIGVTALRM] = "SIGVTALRM", 91147476Sdumbbell [LINUX_SIGPROF] = "SIGPROF", 92147476Sdumbbell [LINUX_SIGWINCH] = "SIGWINCH", 93147476Sdumbbell [LINUX_SIGIO] = "SIGIO", 94147476Sdumbbell [LINUX_SIGPWR] = "SIGPWR", 95147476Sdumbbell [LINUX_SIGSYS] = "SIGSYS", 96147476Sdumbbell 97147476Sdumbbell [LINUX_SIGRTMIN] = "SIGCANCEL", 98147476Sdumbbell [LINUX_SIGRTMIN + 1] = "SIGSETXID", 99147476Sdumbbell [LINUX_SIGRTMIN + 2] = "SIGRT2", 100147476Sdumbbell [LINUX_SIGRTMIN + 3] = "SIGRT3", 101147476Sdumbbell [LINUX_SIGRTMIN + 4] = "SIGRT4", 102147476Sdumbbell [LINUX_SIGRTMIN + 5] = "SIGRT5", 103147476Sdumbbell [LINUX_SIGRTMIN + 6] = "SIGRT6", 104147476Sdumbbell [LINUX_SIGRTMIN + 7] = "SIGRT7", 105147476Sdumbbell [LINUX_SIGRTMIN + 8] = "SIGRT8", 106147476Sdumbbell [LINUX_SIGRTMIN + 9] = "SIGRT9", 107147476Sdumbbell [LINUX_SIGRTMIN + 10] = "SIGRT10", 108147476Sdumbbell [LINUX_SIGRTMIN + 11] = "SIGRT11", 109147476Sdumbbell [LINUX_SIGRTMIN + 12] = "SIGRT12", 110147476Sdumbbell [LINUX_SIGRTMIN + 13] = "SIGRT13", 111147476Sdumbbell [LINUX_SIGRTMIN + 14] = "SIGRT14", 112147476Sdumbbell [LINUX_SIGRTMIN + 15] = "SIGRT15", 113147476Sdumbbell [LINUX_SIGRTMIN + 16] = "SIGRT16", 114147476Sdumbbell [LINUX_SIGRTMIN + 17] = "SIGRT17", 115147476Sdumbbell [LINUX_SIGRTMIN + 18] = "SIGRT18", 116147476Sdumbbell [LINUX_SIGRTMIN + 19] = "SIGRT19", 117147476Sdumbbell [LINUX_SIGRTMIN + 20] = "SIGRT20", 118147476Sdumbbell [LINUX_SIGRTMIN + 21] = "SIGRT21", 119147476Sdumbbell [LINUX_SIGRTMIN + 22] = "SIGRT22", 120147476Sdumbbell [LINUX_SIGRTMIN + 23] = "SIGRT23", 121147476Sdumbbell [LINUX_SIGRTMIN + 24] = "SIGRT24", 122147476Sdumbbell [LINUX_SIGRTMIN + 25] = "SIGRT25", 123147476Sdumbbell [LINUX_SIGRTMIN + 26] = "SIGRT26", 124147476Sdumbbell [LINUX_SIGRTMIN + 27] = "SIGRT27", 125147476Sdumbbell [LINUX_SIGRTMIN + 28] = "SIGRT28", 126147476Sdumbbell [LINUX_SIGRTMIN + 29] = "SIGRT29", 127147476Sdumbbell [LINUX_SIGRTMIN + 30] = "SIGRT30", 128147476Sdumbbell [LINUX_SIGRTMIN + 31] = "SIGRT31", 129147476Sdumbbell [LINUX_SIGRTMIN + 32] = "SIGRTMAX", 130234607Strasz}; 131147476Sdumbbell_Static_assert(nitems(linux_signames) == LINUX_SIGRTMAX + 1, 132147476Sdumbbell "invalid entries count in linux_signames"); 133147476Sdumbbell 134147476Sdumbbellvoid 135147476Sdumbbellsysdecode_linux_clockid(FILE *fp, clockid_t which) 136147476Sdumbbell{ 137147476Sdumbbell const char *str; 138147476Sdumbbell clockid_t ci; 139147476Sdumbbell pid_t pid; 140147476Sdumbbell 141147476Sdumbbell if (which >= 0) { 142147476Sdumbbell str = lookup_value(clockids, which); 143147476Sdumbbell if (str == NULL) 144147476Sdumbbell fprintf(fp, "UNKNOWN(%d)", which); 145147476Sdumbbell else 146147476Sdumbbell fputs(str, fp); 147147476Sdumbbell return; 148147476Sdumbbell } 149147476Sdumbbell if ((which & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD_MASK) { 150147476Sdumbbell fputs("INVALID PERTHREAD|CLOCKFD", fp); 151147476Sdumbbell goto pidp; 152147476Sdumbbell } 153147476Sdumbbell ci = LINUX_CPUCLOCK_WHICH(which); 154184205Sdes if (LINUX_CPUCLOCK_PERTHREAD(which) == true) 155147476Sdumbbell fputs("THREAD|", fp); 156147476Sdumbbell else 157147476Sdumbbell fputs("PROCESS|", fp); 158147476Sdumbbell str = lookup_value(clockcpuids, ci); 159147476Sdumbbell if (str != NULL) 160147476Sdumbbell fputs(str, fp); 161147476Sdumbbell else { 162147476Sdumbbell if (ci == LINUX_CLOCKFD) 163147476Sdumbbell fputs("CLOCKFD", fp); 164147476Sdumbbell else 165147476Sdumbbell fprintf(fp, "UNKNOWN(%d)", which); 166147476Sdumbbell } 167147476Sdumbbell 168147476Sdumbbellpidp: 169147476Sdumbbell pid = LINUX_CPUCLOCK_ID(which); 170147476Sdumbbell fprintf(fp, "(%d)", pid); 171147476Sdumbbell} 172147476Sdumbbell 173147476Sdumbbellconst char * 174147476Sdumbbellsysdecode_linux_signal(int sig) 175147476Sdumbbell{ 176147476Sdumbbell 177147476Sdumbbell if ((unsigned)sig < nitems(linux_signames)) 178147476Sdumbbell return (linux_signames[sig]); 179147476Sdumbbell return (NULL); 180147476Sdumbbell} 181147476Sdumbbell 182147476Sdumbbellconst char * 183147476Sdumbbellsysdecode_linux_sigprocmask_how(int how) 184147476Sdumbbell{ 185147476Sdumbbell 186147476Sdumbbell return (lookup_value(sigprocmaskhow, how)); 187147476Sdumbbell} 188147476Sdumbbell 189147476Sdumbbellbool 190147476Sdumbbellsysdecode_linux_clock_flags(FILE *fp, int flags, int *rem) 191147476Sdumbbell{ 192147476Sdumbbell 193147476Sdumbbell return (print_mask_int(fp, clockflags, flags, rem)); 194147476Sdumbbell} 195147476Sdumbbell 196147476Sdumbbellbool 197147476Sdumbbellsysdecode_linux_atflags(FILE *fp, int flag, int *rem) 198147476Sdumbbell{ 199147476Sdumbbell 200147476Sdumbbell return (print_mask_int(fp, atflags, flag, rem)); 201147476Sdumbbell} 202147476Sdumbbell 203147476Sdumbbellbool 204147476Sdumbbellsysdecode_linux_open_flags(FILE *fp, int flags, int *rem) 205147476Sdumbbell{ 206147476Sdumbbell bool printed; 207147476Sdumbbell int mode; 208147476Sdumbbell uintmax_t val; 209147476Sdumbbell 210147476Sdumbbell mode = flags & LINUX_O_ACCMODE; 211147476Sdumbbell flags &= ~LINUX_O_ACCMODE; 212147476Sdumbbell switch (mode) { 213147476Sdumbbell case LINUX_O_RDONLY: 214147476Sdumbbell fputs("O_RDONLY", fp); 215147476Sdumbbell printed = true; 216147476Sdumbbell mode = 0; 217147476Sdumbbell break; 218147476Sdumbbell case LINUX_O_WRONLY: 219147476Sdumbbell fputs("O_WRONLY", fp); 220147476Sdumbbell printed = true; 221147476Sdumbbell mode = 0; 222147476Sdumbbell break; 223147476Sdumbbell case LINUX_O_RDWR: 224147476Sdumbbell fputs("O_RDWR", fp); 225147476Sdumbbell printed = true; 226147476Sdumbbell mode = 0; 227147476Sdumbbell break; 228147476Sdumbbell default: 229147476Sdumbbell printed = false; 230147476Sdumbbell } 231147476Sdumbbell val = (unsigned)flags; 232147476Sdumbbell print_mask_part(fp, openflags, &val, &printed); 233147476Sdumbbell if (rem != NULL) 234147476Sdumbbell *rem = val | mode; 235147476Sdumbbell return (printed); 236147476Sdumbbell} 237147476Sdumbbell 238147476Sdumbbellbool 239147476Sdumbbellsysdecode_linux_clone_flags(FILE *fp, int flags, int *rem) 240147476Sdumbbell{ 241147476Sdumbbell uintmax_t val; 242147476Sdumbbell bool printed; 243147476Sdumbbell int sig; 244147476Sdumbbell 245147476Sdumbbell sig = flags & LINUX_CSIGNAL; 246147476Sdumbbell if (sig != 0) 247147476Sdumbbell fprintf(fp, "(%s)", sysdecode_linux_signal(sig)); 248147476Sdumbbell val = (unsigned)flags & ~LINUX_CSIGNAL; 249147476Sdumbbell print_mask_part(fp, cloneflags, &val, &printed); 250147476Sdumbbell if (rem != NULL) 251147476Sdumbbell *rem = val; 252147476Sdumbbell return (printed); 253147476Sdumbbell} 254147476Sdumbbell