// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) // Copyright (c) 2020 Anton Protopopov #include #include #include #include #include static const char **syscall_names; static size_t syscall_names_size; #define warn(...) fprintf(stderr, __VA_ARGS__) #define MAX(x, y) (((x) > (y)) ? (x) : (y)) static const char *parse_syscall(const char *buf, int *number) { char *end; long x; errno = 0; x = strtol(buf, &end, 10); if (errno) { warn("strtol(%s): %s\n", buf, strerror(errno)); return NULL; } else if (end == buf) { warn("strtol(%s): no digits found\n", buf); return NULL; } else if (x < 0 || x > INT_MAX) { warn("strtol(%s): bad syscall number: %ld\n", buf, x); return NULL; } if (*end != '\t') { warn("bad input: %s (expected \t)\n", buf); return NULL; } *number = x; return ++end; } void init_syscall_names(void) { size_t old_size, size = 1024; const char *name; char buf[64]; int number; int err; FILE *f; f = popen("ausyscall --dump 2>/dev/null", "r"); if (!f) { warn("popen: ausyscall --dump: %s\n", strerror(errno)); return; } syscall_names = calloc(size, sizeof(char *)); if (!syscall_names) { warn("calloc: %s\n", strerror(errno)); goto close; } /* skip the header, ignore the result of fgets, outwit the comiler */ (void) !!fgets(buf, sizeof(buf), f); while (fgets(buf, sizeof(buf), f)) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; name = parse_syscall(buf, &number); if (!name || !name[0]) goto close; /* In a rare case when syscall number is > than initial 1024 */ if (number >= size) { old_size = size; size = 1024 * (1 + number / 1024); syscall_names = realloc(syscall_names, size * sizeof(char *)); if (!syscall_names) { warn("realloc: %s\n", strerror(errno)); goto close; } memset(syscall_names+old_size, 0, (size - old_size) * sizeof(char *)); } if (syscall_names[number]) { warn("duplicate number: %d (stored: %s)", number, syscall_names[number]); goto close; } syscall_names[number] = strdup(name); if (!syscall_names[number]) { warn("strdup: %s\n", strerror(errno)); goto close; } syscall_names_size = MAX(number+1, syscall_names_size); } if (ferror(f)) warn("fgets: %s\n", strerror(errno)); close: err = pclose(f); if (err < 0) warn("pclose: %s\n", strerror(errno)); #ifndef __x86_64__ /* Ignore the error for x86_64 where we have a table compiled in */ else if (err && WEXITSTATUS(err) == 127) { warn("ausyscall required for syscalls number/name mapping\n"); } else if (err) { warn("ausyscall exit status (see wait(2)): 0x%x\n", err); } #endif } void free_syscall_names(void) { size_t i; for (i = 0; i < syscall_names_size; i++) free((void *) syscall_names[i]); free(syscall_names); } /* * Syscall table for Linux x86_64. * * Semi-automatically generated from strace/linux/x86_64/syscallent.h and * linux/syscallent-common.h using the following commands: * * awk -F\" '/SEN/{printf("%d %s\n", substr($0,2,3), $(NF-1));}' syscallent.h * awk '/SEN/ { printf("%d %s\n", $3, $9); }' syscallent-common.h * * (The idea is taken from src/python/bcc/syscall.py.) */ #ifdef __x86_64__ static const char *syscall_names_x86_64[] = { [0] = "read", [1] = "write", [2] = "open", [3] = "close", [4] = "stat", [5] = "fstat", [6] = "lstat", [7] = "poll", [8] = "lseek", [9] = "mmap", [10] = "mprotect", [11] = "munmap", [12] = "brk", [13] = "rt_sigaction", [14] = "rt_sigprocmask", [15] = "rt_sigreturn", [16] = "ioctl", [17] = "pread64", [18] = "pwrite64", [19] = "readv", [20] = "writev", [21] = "access", [22] = "pipe", [23] = "select", [24] = "sched_yield", [25] = "mremap", [26] = "msync", [27] = "mincore", [28] = "madvise", [29] = "shmget", [30] = "shmat", [31] = "shmctl", [32] = "dup", [33] = "dup2", [34] = "pause", [35] = "nanosleep", [36] = "getitimer", [37] = "alarm", [38] = "setitimer", [39] = "getpid", [40] = "sendfile", [41] = "socket", [42] = "connect", [43] = "accept", [44] = "sendto", [45] = "recvfrom", [46] = "sendmsg", [47] = "recvmsg", [48] = "shutdown", [49] = "bind", [50] = "listen", [51] = "getsockname", [52] = "getpeername", [53] = "socketpair", [54] = "setsockopt", [55] = "getsockopt", [56] = "clone", [57] = "fork", [58] = "vfork", [59] = "execve", [60] = "exit", [61] = "wait4", [62] = "kill", [63] = "uname", [64] = "semget", [65] = "semop", [66] = "semctl", [67] = "shmdt", [68] = "msgget", [69] = "msgsnd", [70] = "msgrcv", [71] = "msgctl", [72] = "fcntl", [73] = "flock", [74] = "fsync", [75] = "fdatasync", [76] = "truncate", [77] = "ftruncate", [78] = "getdents", [79] = "getcwd", [80] = "chdir", [81] = "fchdir", [82] = "rename", [83] = "mkdir", [84] = "rmdir", [85] = "creat", [86] = "link", [87] = "unlink", [88] = "symlink", [89] = "readlink", [90] = "chmod", [91] = "fchmod", [92] = "chown", [93] = "fchown", [94] = "lchown", [95] = "umask", [96] = "gettimeofday", [97] = "getrlimit", [98] = "getrusage", [99] = "sysinfo", [100] = "times", [101] = "ptrace", [102] = "getuid", [103] = "syslog", [104] = "getgid", [105] = "setuid", [106] = "setgid", [107] = "geteuid", [108] = "getegid", [109] = "setpgid", [110] = "getppid", [111] = "getpgrp", [112] = "setsid", [113] = "setreuid", [114] = "setregid", [115] = "getgroups", [116] = "setgroups", [117] = "setresuid", [118] = "getresuid", [119] = "setresgid", [120] = "getresgid", [121] = "getpgid", [122] = "setfsuid", [123] = "setfsgid", [124] = "getsid", [125] = "capget", [126] = "capset", [127] = "rt_sigpending", [128] = "rt_sigtimedwait", [129] = "rt_sigqueueinfo", [130] = "rt_sigsuspend", [131] = "sigaltstack", [132] = "utime", [133] = "mknod", [134] = "uselib", [135] = "personality", [136] = "ustat", [137] = "statfs", [138] = "fstatfs", [139] = "sysfs", [140] = "getpriority", [141] = "setpriority", [142] = "sched_setparam", [143] = "sched_getparam", [144] = "sched_setscheduler", [145] = "sched_getscheduler", [146] = "sched_get_priority_max", [147] = "sched_get_priority_min", [148] = "sched_rr_get_interval", [149] = "mlock", [150] = "munlock", [151] = "mlockall", [152] = "munlockall", [153] = "vhangup", [154] = "modify_ldt", [155] = "pivot_root", [156] = "_sysctl", [157] = "prctl", [158] = "arch_prctl", [159] = "adjtimex", [160] = "setrlimit", [161] = "chroot", [162] = "sync", [163] = "acct", [164] = "settimeofday", [165] = "mount", [166] = "umount2", [167] = "swapon", [168] = "swapoff", [169] = "reboot", [170] = "sethostname", [171] = "setdomainname", [172] = "iopl", [173] = "ioperm", [174] = "create_module", [175] = "init_module", [176] = "delete_module", [177] = "get_kernel_syms", [178] = "query_module", [179] = "quotactl", [180] = "nfsservctl", [181] = "getpmsg", [182] = "putpmsg", [183] = "afs_syscall", [184] = "tuxcall", [185] = "security", [186] = "gettid", [187] = "readahead", [188] = "setxattr", [189] = "lsetxattr", [190] = "fsetxattr", [191] = "getxattr", [192] = "lgetxattr", [193] = "fgetxattr", [194] = "listxattr", [195] = "llistxattr", [196] = "flistxattr", [197] = "removexattr", [198] = "lremovexattr", [199] = "fremovexattr", [200] = "tkill", [201] = "time", [202] = "futex", [203] = "sched_setaffinity", [204] = "sched_getaffinity", [205] = "set_thread_area", [206] = "io_setup", [207] = "io_destroy", [208] = "io_getevents", [209] = "io_submit", [210] = "io_cancel", [211] = "get_thread_area", [212] = "lookup_dcookie", [213] = "epoll_create", [214] = "epoll_ctl_old", [215] = "epoll_wait_old", [216] = "remap_file_pages", [217] = "getdents64", [218] = "set_tid_address", [219] = "restart_syscall", [220] = "semtimedop", [221] = "fadvise64", [222] = "timer_create", [223] = "timer_settime", [224] = "timer_gettime", [225] = "timer_getoverrun", [226] = "timer_delete", [227] = "clock_settime", [228] = "clock_gettime", [229] = "clock_getres", [230] = "clock_nanosleep", [231] = "exit_group", [232] = "epoll_wait", [233] = "epoll_ctl", [234] = "tgkill", [235] = "utimes", [236] = "vserver", [237] = "mbind", [238] = "set_mempolicy", [239] = "get_mempolicy", [240] = "mq_open", [241] = "mq_unlink", [242] = "mq_timedsend", [243] = "mq_timedreceive", [244] = "mq_notify", [245] = "mq_getsetattr", [246] = "kexec_load", [247] = "waitid", [248] = "add_key", [249] = "request_key", [250] = "keyctl", [251] = "ioprio_set", [252] = "ioprio_get", [253] = "inotify_init", [254] = "inotify_add_watch", [255] = "inotify_rm_watch", [256] = "migrate_pages", [257] = "openat", [258] = "mkdirat", [259] = "mknodat", [260] = "fchownat", [261] = "futimesat", [262] = "newfstatat", [263] = "unlinkat", [264] = "renameat", [265] = "linkat", [266] = "symlinkat", [267] = "readlinkat", [268] = "fchmodat", [269] = "faccessat", [270] = "pselect6", [271] = "ppoll", [272] = "unshare", [273] = "set_robust_list", [274] = "get_robust_list", [275] = "splice", [276] = "tee", [277] = "sync_file_range", [278] = "vmsplice", [279] = "move_pages", [280] = "utimensat", [281] = "epoll_pwait", [282] = "signalfd", [283] = "timerfd_create", [284] = "eventfd", [285] = "fallocate", [286] = "timerfd_settime", [287] = "timerfd_gettime", [288] = "accept4", [289] = "signalfd4", [290] = "eventfd2", [291] = "epoll_create1", [292] = "dup3", [293] = "pipe2", [294] = "inotify_init1", [295] = "preadv", [296] = "pwritev", [297] = "rt_tgsigqueueinfo", [298] = "perf_event_open", [299] = "recvmmsg", [300] = "fanotify_init", [301] = "fanotify_mark", [302] = "prlimit64", [303] = "name_to_handle_at", [304] = "open_by_handle_at", [305] = "clock_adjtime", [306] = "syncfs", [307] = "sendmmsg", [308] = "setns", [309] = "getcpu", [310] = "process_vm_readv", [311] = "process_vm_writev", [312] = "kcmp", [313] = "finit_module", [314] = "sched_setattr", [315] = "sched_getattr", [316] = "renameat2", [317] = "seccomp", [318] = "getrandom", [319] = "memfd_create", [320] = "kexec_file_load", [321] = "bpf", [322] = "execveat", [323] = "userfaultfd", [324] = "membarrier", [325] = "mlock2", [326] = "copy_file_range", [327] = "preadv2", [328] = "pwritev2", [329] = "pkey_mprotect", [330] = "pkey_alloc", [331] = "pkey_free", [332] = "statx", [333] = "io_pgetevents", [334] = "rseq", [424] = "pidfd_send_signal", [425] = "io_uring_setup", [426] = "io_uring_enter", [427] = "io_uring_register", [428] = "open_tree", [429] = "move_mount", [430] = "fsopen", [431] = "fsconfig", [432] = "fsmount", [433] = "fspick", [434] = "pidfd_open", [435] = "clone3", [437] = "openat2", [438] = "pidfd_getfd", }; size_t syscall_names_x86_64_size = sizeof(syscall_names_x86_64)/sizeof(char*); #endif void syscall_name(unsigned n, char *buf, size_t size) { const char *name = NULL; if (n < syscall_names_size) name = syscall_names[n]; #ifdef __x86_64__ else if (n < syscall_names_x86_64_size) name = syscall_names_x86_64[n]; #endif if (name) strncpy(buf, name, size-1); else snprintf(buf, size, "[unknown: %u]", n); } int list_syscalls(void) { const char **list = syscall_names; size_t i, size = syscall_names_size; #ifdef __x86_64__ if (!size) { size = syscall_names_x86_64_size; list = syscall_names_x86_64; } #endif for (i = 0; i < size; i++) { if (list[i]) printf("%3zd: %s\n", i, list[i]); } return (!list || !size); }