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; 9039de84b6SDmitry Chagin case LINUX_SYS_linux_clock_nanosleep: 9139de84b6SDmitry Chagin putchar('('); 9239de84b6SDmitry Chagin sysdecode_linux_clockid(stdout, *ip); 9339de84b6SDmitry Chagin putchar(','); 9439de84b6SDmitry Chagin ip++; 9539de84b6SDmitry Chagin narg--; 9639de84b6SDmitry Chagin print_mask_arg0(sysdecode_linux_clock_flags, *ip); 9739de84b6SDmitry Chagin c = ','; 9839de84b6SDmitry Chagin ip++; 9939de84b6SDmitry Chagin narg--; 10039de84b6SDmitry Chagin break; 1018a0f6d8cSDmitry Chagin case LINUX_SYS_linux_kill: 1028a0f6d8cSDmitry Chagin case LINUX_SYS_linux_tkill: 1038a0f6d8cSDmitry Chagin case LINUX_SYS_linux_rt_sigqueueinfo: 1048a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1058a0f6d8cSDmitry Chagin putchar(','); 1068a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1078a0f6d8cSDmitry Chagin ip++; 1088a0f6d8cSDmitry Chagin narg--; 1098a0f6d8cSDmitry Chagin break; 1108a0f6d8cSDmitry Chagin case LINUX_SYS_linux_tgkill: 1118a0f6d8cSDmitry Chagin case LINUX_SYS_linux_rt_tgsigqueueinfo: 1128a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1138a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1148a0f6d8cSDmitry Chagin putchar(','); 1158a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1168a0f6d8cSDmitry Chagin ip++; 1178a0f6d8cSDmitry Chagin narg--; 1188a0f6d8cSDmitry Chagin break; 1198a0f6d8cSDmitry Chagin case LINUX_SYS_linux_rt_sigaction: 1208a0f6d8cSDmitry Chagin putchar('('); 1218a0f6d8cSDmitry Chagin print_linux_signal(*ip); 1228a0f6d8cSDmitry Chagin ip++; 1238a0f6d8cSDmitry Chagin narg--; 1248a0f6d8cSDmitry Chagin c = ','; 1258a0f6d8cSDmitry Chagin break; 1268a0f6d8cSDmitry Chagin case LINUX_SYS_linux_ftruncate: 1278a0f6d8cSDmitry Chagin case LINUX_SYS_linux_truncate: 1288a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1298a0f6d8cSDmitry Chagin print_number64(first, ip, narg, c); 1308a0f6d8cSDmitry Chagin break; 131b9b86b67SDmitry Chagin case LINUX_SYS_linux_getitimer: 132b9b86b67SDmitry Chagin case LINUX_SYS_linux_setitimer: 133b9b86b67SDmitry Chagin putchar('('); 134b9b86b67SDmitry Chagin print_integer_arg(sysdecode_itimer, *ip); 135b9b86b67SDmitry Chagin ip++; 136b9b86b67SDmitry Chagin narg--; 137b9b86b67SDmitry Chagin c = ','; 138b9b86b67SDmitry Chagin break; 139f587a2a7SDmitry Chagin case LINUX_SYS_linux_rt_sigprocmask: 140f587a2a7SDmitry Chagin #ifdef LINUX_SYS_linux_sigprocmask 141f587a2a7SDmitry Chagin case LINUX_SYS_linux_sigprocmask: 142f587a2a7SDmitry Chagin #endif 143f587a2a7SDmitry Chagin putchar('('); 144f587a2a7SDmitry Chagin print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 145f587a2a7SDmitry Chagin ip++; 146f587a2a7SDmitry Chagin narg--; 147f587a2a7SDmitry Chagin c = ','; 148f587a2a7SDmitry Chagin break; 1498a0f6d8cSDmitry Chagin } 1508a0f6d8cSDmitry Chagin *resc = c; 1518a0f6d8cSDmitry Chagin *resip = ip; 1528a0f6d8cSDmitry Chagin *resnarg = narg; 1538a0f6d8cSDmitry Chagin } 1548a0f6d8cSDmitry Chagin 1558a0f6d8cSDmitry Chagin #if defined(__amd64__) 1568a0f6d8cSDmitry Chagin void 1578a0f6d8cSDmitry Chagin ktrsyscall_linux32(struct ktr_syscall *ktr, register_t **resip, 1588a0f6d8cSDmitry Chagin int *resnarg, char *resc) 1598a0f6d8cSDmitry Chagin { 1608a0f6d8cSDmitry Chagin int narg = ktr->ktr_narg; 1618a0f6d8cSDmitry Chagin register_t *ip, *first; 1628a0f6d8cSDmitry Chagin int quad_align, quad_slots; 1638a0f6d8cSDmitry Chagin char c; 1648a0f6d8cSDmitry Chagin 1658a0f6d8cSDmitry Chagin ip = first = &ktr->ktr_args[0]; 1668a0f6d8cSDmitry Chagin c = *resc; 1678a0f6d8cSDmitry Chagin quad_align = 0; 1688a0f6d8cSDmitry Chagin quad_slots = 2; 1698a0f6d8cSDmitry Chagin switch (ktr->ktr_code) { 1708a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_gettime: 1718a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_settime: 1728a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_getres: 1738a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_timer_create: 1748a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_gettime64: 1758a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_settime64: 1768a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_clock_getres_time64: 1778a0f6d8cSDmitry Chagin putchar('('); 1788a0f6d8cSDmitry Chagin sysdecode_linux_clockid(stdout, *ip); 1798a0f6d8cSDmitry Chagin c = ','; 1808a0f6d8cSDmitry Chagin ip++; 1818a0f6d8cSDmitry Chagin narg--; 1828a0f6d8cSDmitry Chagin break; 18339de84b6SDmitry Chagin case LINUX32_SYS_linux_clock_nanosleep: 18439de84b6SDmitry Chagin putchar('('); 18539de84b6SDmitry Chagin sysdecode_linux_clockid(stdout, *ip); 18639de84b6SDmitry Chagin putchar(','); 18739de84b6SDmitry Chagin ip++; 18839de84b6SDmitry Chagin narg--; 18939de84b6SDmitry Chagin print_mask_arg0(sysdecode_linux_clock_flags, *ip); 19039de84b6SDmitry Chagin c = ','; 19139de84b6SDmitry Chagin ip++; 19239de84b6SDmitry Chagin narg--; 19339de84b6SDmitry Chagin break; 1948a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_kill: 1958a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_tkill: 1968a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_rt_sigqueueinfo: 1978a0f6d8cSDmitry Chagin print_number(ip, narg, c); 1988a0f6d8cSDmitry Chagin putchar(','); 1998a0f6d8cSDmitry Chagin print_linux_signal(*ip); 2008a0f6d8cSDmitry Chagin ip++; 2018a0f6d8cSDmitry Chagin narg--; 2028a0f6d8cSDmitry Chagin break; 2038a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_tgkill: 2048a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_rt_tgsigqueueinfo: 2058a0f6d8cSDmitry Chagin print_number(ip, narg, c); 2068a0f6d8cSDmitry Chagin print_number(ip, narg, c); 2078a0f6d8cSDmitry Chagin putchar(','); 2088a0f6d8cSDmitry Chagin print_linux_signal(*ip); 2098a0f6d8cSDmitry Chagin ip++; 2108a0f6d8cSDmitry Chagin narg--; 2118a0f6d8cSDmitry Chagin break; 2128a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_signal: 2138a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_sigaction: 2148a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_rt_sigaction: 2158a0f6d8cSDmitry Chagin putchar('('); 2168a0f6d8cSDmitry Chagin print_linux_signal(*ip); 2178a0f6d8cSDmitry Chagin ip++; 2188a0f6d8cSDmitry Chagin narg--; 2198a0f6d8cSDmitry Chagin c = ','; 2208a0f6d8cSDmitry Chagin break; 2218a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_ftruncate: 2228a0f6d8cSDmitry Chagin case LINUX32_SYS_linux_truncate: 2238a0f6d8cSDmitry Chagin print_number(ip, narg, c); 2248a0f6d8cSDmitry Chagin print_number64(first, ip, narg, c); 2258a0f6d8cSDmitry Chagin break; 226b9b86b67SDmitry Chagin case LINUX32_SYS_linux_getitimer: 227b9b86b67SDmitry Chagin case LINUX32_SYS_linux_setitimer: 228b9b86b67SDmitry Chagin putchar('('); 229b9b86b67SDmitry Chagin print_integer_arg(sysdecode_itimer, *ip); 230b9b86b67SDmitry Chagin ip++; 231b9b86b67SDmitry Chagin narg--; 232b9b86b67SDmitry Chagin c = ','; 233b9b86b67SDmitry Chagin break; 234f587a2a7SDmitry Chagin case LINUX32_SYS_linux_rt_sigprocmask: 235f587a2a7SDmitry Chagin case LINUX32_SYS_linux_sigprocmask: 236f587a2a7SDmitry Chagin putchar('('); 237f587a2a7SDmitry Chagin print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 238f587a2a7SDmitry Chagin ip++; 239f587a2a7SDmitry Chagin narg--; 240f587a2a7SDmitry Chagin c = ','; 241f587a2a7SDmitry Chagin break; 2428a0f6d8cSDmitry Chagin } 2438a0f6d8cSDmitry Chagin *resc = c; 2448a0f6d8cSDmitry Chagin *resip = ip; 2458a0f6d8cSDmitry Chagin *resnarg = narg; 2468a0f6d8cSDmitry Chagin } 2478a0f6d8cSDmitry Chagin #endif /* __amd64__ */ 2483606a213SDmitry Chagin 2493606a213SDmitry Chagin static void 2503606a213SDmitry Chagin ktrsigset(const char *name, const l_sigset_t *mask, size_t sz) 2513606a213SDmitry Chagin { 2523606a213SDmitry Chagin unsigned long i, c; 2533606a213SDmitry Chagin 2543606a213SDmitry Chagin printf("%s [ ", name); 2553606a213SDmitry Chagin c = 0; 2563606a213SDmitry Chagin for (i = 1; i <= sz * CHAR_BIT; i++) { 2573606a213SDmitry Chagin if (!LINUX_SIGISMEMBER(*mask, i)) 2583606a213SDmitry Chagin continue; 2593606a213SDmitry Chagin if (c != 0) 2603606a213SDmitry Chagin printf(", "); 2613606a213SDmitry Chagin printf("%s", sysdecode_linux_signal(i)); 2623606a213SDmitry Chagin c++; 2633606a213SDmitry Chagin } 2643606a213SDmitry Chagin if (c == 0) 2653606a213SDmitry Chagin printf("empty ]\n"); 2663606a213SDmitry Chagin else 2673606a213SDmitry Chagin printf(" ]\n"); 2683606a213SDmitry Chagin } 2693606a213SDmitry Chagin 2703606a213SDmitry Chagin bool 2713606a213SDmitry Chagin ktrstruct_linux(const char *name, const char *data, size_t datalen) 2723606a213SDmitry Chagin { 2733606a213SDmitry Chagin l_sigset_t mask; 2743606a213SDmitry Chagin 2753606a213SDmitry Chagin if (strcmp(name, "l_sigset_t") == 0) { 2763606a213SDmitry Chagin /* Old Linux sigset_t is one word size. */ 2773606a213SDmitry Chagin if (datalen < sizeof(int) || datalen > sizeof(l_sigset_t)) 2783606a213SDmitry Chagin return (false); 2793606a213SDmitry Chagin memcpy(&mask, data, datalen); 2803606a213SDmitry Chagin ktrsigset(name, &mask, datalen); 2813606a213SDmitry Chagin } else 2823606a213SDmitry Chagin return (false); 2833606a213SDmitry Chagin 2843606a213SDmitry Chagin return (true); 2853606a213SDmitry Chagin } 286