18a0f6d8cSDmitry Chagin /*- 28a0f6d8cSDmitry Chagin * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 38a0f6d8cSDmitry Chagin * 48a0f6d8cSDmitry Chagin * Copyright (c) 2022 Dmitry Chagin <dchagin@FreeBSD.org> 58a0f6d8cSDmitry Chagin * 68a0f6d8cSDmitry Chagin * Redistribution and use in source and binary forms, with or without 78a0f6d8cSDmitry Chagin * modification, are permitted provided that the following conditions 88a0f6d8cSDmitry Chagin * are met: 98a0f6d8cSDmitry Chagin * 1. Redistributions of source code must retain the above copyright 108a0f6d8cSDmitry Chagin * notice, this list of conditions and the following disclaimer. 118a0f6d8cSDmitry Chagin * 2. Redistributions in binary form must reproduce the above copyright 128a0f6d8cSDmitry Chagin * notice, this list of conditions and the following disclaimer in the 138a0f6d8cSDmitry Chagin * documentation and/or other materials provided with the distribution. 148a0f6d8cSDmitry Chagin * 158a0f6d8cSDmitry Chagin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 168a0f6d8cSDmitry Chagin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 178a0f6d8cSDmitry Chagin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 188a0f6d8cSDmitry Chagin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 198a0f6d8cSDmitry Chagin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 208a0f6d8cSDmitry Chagin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 218a0f6d8cSDmitry Chagin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 228a0f6d8cSDmitry Chagin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 238a0f6d8cSDmitry Chagin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 248a0f6d8cSDmitry Chagin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 258a0f6d8cSDmitry Chagin * SUCH DAMAGE. 268a0f6d8cSDmitry Chagin */ 278a0f6d8cSDmitry Chagin 288a0f6d8cSDmitry Chagin #include <sys/cdefs.h> 298a0f6d8cSDmitry Chagin __FBSDID("$FreeBSD$"); 308a0f6d8cSDmitry Chagin 318a0f6d8cSDmitry Chagin #include <sys/param.h> 328a0f6d8cSDmitry Chagin #include <sys/uio.h> 338a0f6d8cSDmitry Chagin #include <sys/ktrace.h> 343606a213SDmitry Chagin #include <err.h> 353606a213SDmitry Chagin #include <errno.h> 368a0f6d8cSDmitry Chagin #include <stddef.h> 373606a213SDmitry Chagin #include <stdlib.h> 383606a213SDmitry Chagin #include <string.h> 398a0f6d8cSDmitry Chagin #include <sysdecode.h> 408a0f6d8cSDmitry Chagin 418a0f6d8cSDmitry Chagin #include "kdump.h" 428a0f6d8cSDmitry Chagin 438a0f6d8cSDmitry Chagin #ifdef __amd64__ 448a0f6d8cSDmitry Chagin #include <amd64/linux/linux_syscall.h> 458a0f6d8cSDmitry Chagin #include <amd64/linux32/linux32_syscall.h> 468a0f6d8cSDmitry Chagin #elif __aarch64__ 478a0f6d8cSDmitry Chagin #include <arm64/linux/linux_syscall.h> 488a0f6d8cSDmitry Chagin #elif __i386__ 498a0f6d8cSDmitry Chagin #include <i386/linux/linux_syscall.h> 508a0f6d8cSDmitry Chagin #endif 518a0f6d8cSDmitry Chagin 523606a213SDmitry Chagin #include <compat/linux/linux.h> 533606a213SDmitry Chagin 548a0f6d8cSDmitry Chagin static void 558a0f6d8cSDmitry Chagin print_linux_signal(int signo) 568a0f6d8cSDmitry Chagin { 578a0f6d8cSDmitry Chagin const char *signame; 588a0f6d8cSDmitry Chagin 598a0f6d8cSDmitry Chagin signame = sysdecode_linux_signal(signo); 608a0f6d8cSDmitry Chagin if (signame != NULL) 618a0f6d8cSDmitry Chagin printf("%s", signame); 628a0f6d8cSDmitry Chagin else 638a0f6d8cSDmitry Chagin printf("SIG %d", signo); 648a0f6d8cSDmitry Chagin } 658a0f6d8cSDmitry Chagin 668a0f6d8cSDmitry Chagin void 678a0f6d8cSDmitry Chagin ktrsyscall_linux(struct ktr_syscall *ktr, register_t **resip, 688a0f6d8cSDmitry Chagin int *resnarg, char *resc) 698a0f6d8cSDmitry Chagin { 708a0f6d8cSDmitry Chagin int narg = ktr->ktr_narg; 718a0f6d8cSDmitry Chagin register_t *ip, *first; 728a0f6d8cSDmitry Chagin int quad_align, quad_slots; 738a0f6d8cSDmitry Chagin char c; 748a0f6d8cSDmitry Chagin 758a0f6d8cSDmitry Chagin ip = first = &ktr->ktr_args[0]; 768a0f6d8cSDmitry Chagin c = *resc; 778a0f6d8cSDmitry Chagin quad_align = 0; 788a0f6d8cSDmitry Chagin quad_slots = 1; 798a0f6d8cSDmitry Chagin switch (ktr->ktr_code) { 808a0f6d8cSDmitry Chagin case LINUX_SYS_linux_clock_gettime: 818a0f6d8cSDmitry Chagin case LINUX_SYS_linux_clock_settime: 828a0f6d8cSDmitry Chagin case LINUX_SYS_linux_clock_getres: 838a0f6d8cSDmitry Chagin case LINUX_SYS_linux_timer_create: 848a0f6d8cSDmitry Chagin putchar('('); 858a0f6d8cSDmitry Chagin sysdecode_linux_clockid(stdout, *ip); 868a0f6d8cSDmitry Chagin c = ','; 878a0f6d8cSDmitry Chagin ip++; 888a0f6d8cSDmitry Chagin narg--; 898a0f6d8cSDmitry Chagin break; 908a0f6d8cSDmitry Chagin case LINUX_SYS_linux_kill: 918a0f6d8cSDmitry Chagin case LINUX_SYS_linux_tkill: 928a0f6d8cSDmitry Chagin case LINUX_SYS_linux_rt_sigqueueinfo: 938a0f6d8cSDmitry Chagin print_number(ip, narg, c); 948a0f6d8cSDmitry Chagin putchar(','); 958a0f6d8cSDmitry Chagin print_linux_signal(*ip); 968a0f6d8cSDmitry Chagin ip++; 978a0f6d8cSDmitry Chagin narg--; 988a0f6d8cSDmitry Chagin break; 998a0f6d8cSDmitry Chagin case LINUX_SYS_linux_tgkill: 1008a0f6d8cSDmitry Chagin case LINUX_SYS_linux_rt_tgsigqueueinfo: 1018a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1028a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1038a0f6d8cSDmitry Chagin putchar(','); 1048a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1058a0f6d8cSDmitry Chagin ip++; 1068a0f6d8cSDmitry Chagin narg--; 1078a0f6d8cSDmitry Chagin break; 1088a0f6d8cSDmitry Chagin case LINUX_SYS_linux_rt_sigaction: 1098a0f6d8cSDmitry Chagin putchar('('); 1108a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1118a0f6d8cSDmitry Chagin ip++; 1128a0f6d8cSDmitry Chagin narg--; 1138a0f6d8cSDmitry Chagin c = ','; 1148a0f6d8cSDmitry Chagin break; 1158a0f6d8cSDmitry Chagin case LINUX_SYS_linux_ftruncate: 1168a0f6d8cSDmitry Chagin case LINUX_SYS_linux_truncate: 1178a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1188a0f6d8cSDmitry Chagin print_number64(first, ip, narg, c); 1198a0f6d8cSDmitry Chagin break; 120b9b86b67SDmitry Chagin case LINUX_SYS_linux_getitimer: 121b9b86b67SDmitry Chagin case LINUX_SYS_linux_setitimer: 122b9b86b67SDmitry Chagin putchar('('); 123b9b86b67SDmitry Chagin print_integer_arg(sysdecode_itimer, *ip); 124b9b86b67SDmitry Chagin ip++; 125b9b86b67SDmitry Chagin narg--; 126b9b86b67SDmitry Chagin c = ','; 127b9b86b67SDmitry Chagin break; 128f587a2a7SDmitry Chagin case LINUX_SYS_linux_rt_sigprocmask: 129f587a2a7SDmitry Chagin #ifdef LINUX_SYS_linux_sigprocmask 130f587a2a7SDmitry Chagin case LINUX_SYS_linux_sigprocmask: 131f587a2a7SDmitry Chagin #endif 132f587a2a7SDmitry Chagin putchar('('); 133f587a2a7SDmitry Chagin print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 134f587a2a7SDmitry Chagin ip++; 135f587a2a7SDmitry Chagin narg--; 136f587a2a7SDmitry Chagin c = ','; 137f587a2a7SDmitry Chagin break; 1388a0f6d8cSDmitry Chagin } 1398a0f6d8cSDmitry Chagin *resc = c; 1408a0f6d8cSDmitry Chagin *resip = ip; 1418a0f6d8cSDmitry Chagin *resnarg = narg; 1428a0f6d8cSDmitry Chagin } 1438a0f6d8cSDmitry Chagin 1448a0f6d8cSDmitry Chagin #if defined(__amd64__) 1458a0f6d8cSDmitry Chagin void 1468a0f6d8cSDmitry Chagin ktrsyscall_linux32(struct ktr_syscall *ktr, register_t **resip, 1478a0f6d8cSDmitry Chagin int *resnarg, char *resc) 1488a0f6d8cSDmitry Chagin { 1498a0f6d8cSDmitry Chagin int narg = ktr->ktr_narg; 1508a0f6d8cSDmitry Chagin register_t *ip, *first; 1518a0f6d8cSDmitry Chagin int quad_align, quad_slots; 1528a0f6d8cSDmitry Chagin char c; 1538a0f6d8cSDmitry Chagin 1548a0f6d8cSDmitry Chagin ip = first = &ktr->ktr_args[0]; 1558a0f6d8cSDmitry Chagin c = *resc; 1568a0f6d8cSDmitry Chagin quad_align = 0; 1578a0f6d8cSDmitry Chagin quad_slots = 2; 1588a0f6d8cSDmitry Chagin switch (ktr->ktr_code) { 1598a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_gettime: 1608a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_settime: 1618a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_getres: 1628a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_timer_create: 1638a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_gettime64: 1648a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_settime64: 1658a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_getres_time64: 1668a0f6d8cSDmitry Chagin putchar('('); 1678a0f6d8cSDmitry Chagin sysdecode_linux_clockid(stdout, *ip); 1688a0f6d8cSDmitry Chagin c = ','; 1698a0f6d8cSDmitry Chagin ip++; 1708a0f6d8cSDmitry Chagin narg--; 1718a0f6d8cSDmitry Chagin break; 1728a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_kill: 1738a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_tkill: 1748a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_rt_sigqueueinfo: 1758a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1768a0f6d8cSDmitry Chagin putchar(','); 1778a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1788a0f6d8cSDmitry Chagin ip++; 1798a0f6d8cSDmitry Chagin narg--; 1808a0f6d8cSDmitry Chagin break; 1818a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_tgkill: 1828a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_rt_tgsigqueueinfo: 1838a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1848a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1858a0f6d8cSDmitry Chagin putchar(','); 1868a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1878a0f6d8cSDmitry Chagin ip++; 1888a0f6d8cSDmitry Chagin narg--; 1898a0f6d8cSDmitry Chagin break; 1908a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_signal: 1918a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_sigaction: 1928a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_rt_sigaction: 1938a0f6d8cSDmitry Chagin putchar('('); 1948a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1958a0f6d8cSDmitry Chagin ip++; 1968a0f6d8cSDmitry Chagin narg--; 1978a0f6d8cSDmitry Chagin c = ','; 1988a0f6d8cSDmitry Chagin break; 1998a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_ftruncate: 2008a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_truncate: 2018a0f6d8cSDmitry Chagin print_number(ip, narg, c); 2028a0f6d8cSDmitry Chagin print_number64(first, ip, narg, c); 2038a0f6d8cSDmitry Chagin break; 204b9b86b67SDmitry Chagin case LINUX32_SYS_linux_getitimer: 205b9b86b67SDmitry Chagin case LINUX32_SYS_linux_setitimer: 206b9b86b67SDmitry Chagin putchar('('); 207b9b86b67SDmitry Chagin print_integer_arg(sysdecode_itimer, *ip); 208b9b86b67SDmitry Chagin ip++; 209b9b86b67SDmitry Chagin narg--; 210b9b86b67SDmitry Chagin c = ','; 211b9b86b67SDmitry Chagin break; 212f587a2a7SDmitry Chagin case LINUX32_SYS_linux_rt_sigprocmask: 213f587a2a7SDmitry Chagin case LINUX32_SYS_linux_sigprocmask: 214f587a2a7SDmitry Chagin putchar('('); 215f587a2a7SDmitry Chagin print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 216f587a2a7SDmitry Chagin ip++; 217f587a2a7SDmitry Chagin narg--; 218f587a2a7SDmitry Chagin c = ','; 219f587a2a7SDmitry Chagin break; 2208a0f6d8cSDmitry Chagin } 2218a0f6d8cSDmitry Chagin *resc = c; 2228a0f6d8cSDmitry Chagin *resip = ip; 2238a0f6d8cSDmitry Chagin *resnarg = narg; 2248a0f6d8cSDmitry Chagin } 2258a0f6d8cSDmitry Chagin #endif /* __amd64__ */ 2263606a213SDmitry Chagin 2273606a213SDmitry Chagin static void 2283606a213SDmitry Chagin ktrsigset(const char *name, const l_sigset_t *mask, size_t sz) 2293606a213SDmitry Chagin { 2303606a213SDmitry Chagin unsigned long i, c; 2313606a213SDmitry Chagin 2323606a213SDmitry Chagin printf("%s [ ", name); 2333606a213SDmitry Chagin c = 0; 2343606a213SDmitry Chagin for (i = 1; i <= sz * CHAR_BIT; i++) { 2353606a213SDmitry Chagin if (!LINUX_SIGISMEMBER(*mask, i)) 2363606a213SDmitry Chagin continue; 2373606a213SDmitry Chagin if (c != 0) 2383606a213SDmitry Chagin printf(", "); 2393606a213SDmitry Chagin printf("%s", sysdecode_linux_signal(i)); 2403606a213SDmitry Chagin c++; 2413606a213SDmitry Chagin } 2423606a213SDmitry Chagin if (c == 0) 2433606a213SDmitry Chagin printf("empty ]\n"); 2443606a213SDmitry Chagin else 2453606a213SDmitry Chagin printf(" ]\n"); 2463606a213SDmitry Chagin } 2473606a213SDmitry Chagin 2483606a213SDmitry Chagin bool 2493606a213SDmitry Chagin ktrstruct_linux(const char *name, const char *data, size_t datalen) 2503606a213SDmitry Chagin { 2513606a213SDmitry Chagin l_sigset_t mask; 2523606a213SDmitry Chagin 2533606a213SDmitry Chagin if (strcmp(name, "l_sigset_t") == 0) { 2543606a213SDmitry Chagin /* Old Linux sigset_t is one word size. */ 2553606a213SDmitry Chagin if (datalen < sizeof(int) || datalen > sizeof(l_sigset_t)) 2563606a213SDmitry Chagin return (false); 2573606a213SDmitry Chagin memcpy(&mask, data, datalen); 2583606a213SDmitry Chagin ktrsigset(name, &mask, datalen); 2593606a213SDmitry Chagin } else 2603606a213SDmitry Chagin return (false); 2613606a213SDmitry Chagin 2623606a213SDmitry Chagin return (true); 2633606a213SDmitry Chagin } 264