1 /* $NetBSD: freebsd_misc.c,v 1.36 2026/09/20 13:45:28 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Frank van der Linden 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * FreeBSD compatibility module. Try to deal with various FreeBSD system calls. 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: freebsd_misc.c,v 1.36 2026/09/20 13:45:28 riastradh Exp $"); 36 37 #if defined(_KERNEL_OPT) 38 #include "opt_ntp.h" 39 #endif 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/proc.h> 44 #include <sys/mount.h> 45 #include <sys/signal.h> 46 #include <sys/signalvar.h> 47 #include <sys/mman.h> 48 #include <sys/ktrace.h> 49 50 #include <sys/syscallargs.h> 51 52 #include <compat/freebsd/freebsd_syscallargs.h> 53 #include <compat/common/compat_util.h> 54 #include <compat/freebsd/freebsd_rtprio.h> 55 #include <compat/freebsd/freebsd_timex.h> 56 #include <compat/freebsd/freebsd_signal.h> 57 #include <compat/freebsd/freebsd_mman.h> 58 59 int 60 freebsd_sys_msync(struct lwp *l, const struct freebsd_sys_msync_args *uap, register_t *retval) 61 { 62 /* { 63 syscallarg(void *) addr; 64 syscallarg(size_t) len; 65 syscallarg(int) flags; 66 } */ 67 struct sys___msync13_args bma; 68 69 /* 70 * FreeBSD-2.0-RELEASE's msync(2) is compatible with NetBSD's. 71 * FreeBSD-2.0.5-RELEASE's msync(2) has addtional argument `flags', 72 * but syscall number is not changed. :-< 73 */ 74 memset(&bma, 0, sizeof(bma)); 75 SCARG(&bma, addr) = SCARG(uap, addr); 76 SCARG(&bma, len) = SCARG(uap, len); 77 SCARG(&bma, flags) = SCARG(uap, flags); 78 return sys___msync13(l, &bma, retval); 79 } 80 81 int 82 freebsd_sys_mmap(struct lwp *l, const struct freebsd_sys_mmap_args *uap, register_t *retval) 83 { 84 /* { 85 syscallarg(void *) addr; 86 syscallarg(size_t) len; 87 syscallarg(int) prot; 88 syscallarg(int) flags; 89 syscallarg(int) fd; 90 syscallarg(long) pad; 91 syscallarg(off_t) pos; 92 } */ 93 struct sys_mmap_args bma; 94 int flags, prot, fd; 95 off_t pos; 96 97 prot = SCARG(uap, prot); 98 flags = SCARG(uap, flags); 99 fd = SCARG(uap, fd); 100 pos = SCARG(uap, pos); 101 102 /* 103 * If using MAP_STACK on FreeBSD: 104 * 105 * + fd has to be -1 106 * + prot must have read and write 107 * + MAP_STACK implies MAP_ANON 108 * + MAP_STACK implies offset of 0 109 */ 110 if (flags & FREEBSD_MAP_STACK) { 111 if ((fd != -1) 112 ||((prot & (PROT_READ|PROT_WRITE))!=(PROT_READ|PROT_WRITE))) 113 return (EINVAL); 114 115 flags |= (MAP_ANON | MAP_FIXED); 116 flags &= ~FREEBSD_MAP_STACK; 117 118 pos = 0; 119 } 120 121 memset(&bma, 0, sizeof(bma)); 122 SCARG(&bma, addr) = SCARG(uap, addr); 123 SCARG(&bma, len) = SCARG(uap, len); 124 SCARG(&bma, prot) = prot; 125 SCARG(&bma, flags) = flags; 126 SCARG(&bma, fd) = fd; 127 SCARG(&bma, pos) = pos; 128 129 return sys_mmap(l, &bma, retval); 130 } 131 132 /* just a place holder */ 133 134 int 135 freebsd_sys_rtprio(struct lwp *l, const struct freebsd_sys_rtprio_args *uap, register_t *retval) 136 { 137 /* { 138 syscallarg(int) function; 139 syscallarg(pid_t) pid; 140 syscallarg(struct freebsd_rtprio *) rtp; 141 } */ 142 143 return ENOSYS; /* XXX */ 144 } 145 146 #ifdef NTP 147 int 148 freebsd_ntp_adjtime(struct lwp *l, const struct freebsd_ntp_adjtime_args *uap, register_t *retval) 149 { 150 /* { 151 syscallarg(struct freebsd_timex *) tp; 152 } */ 153 154 return ENOSYS; /* XXX */ 155 } 156 #endif 157 158 int 159 freebsd_sys_sigaction4(struct lwp *l, const struct freebsd_sys_sigaction4_args *uap, register_t *retval) 160 { 161 /* { 162 syscallarg(int) signum; 163 syscallarg(const struct freebsd_sigaction4 *) nsa; 164 syscallarg(struct freebsd_sigaction4 *) osa; 165 } */ 166 struct freebsd_sigaction4 nesa, oesa; 167 struct sigaction nbsa, obsa; 168 int error; 169 170 if (SCARG(uap, nsa)) { 171 error = copyin(SCARG(uap, nsa), &nesa, sizeof(nesa)); 172 if (error) 173 return (error); 174 nbsa.sa_handler = nesa.freebsd_sa_handler; 175 nbsa.sa_mask = nesa.freebsd_sa_mask; 176 nbsa.sa_flags = nesa.freebsd_sa_flags; 177 } 178 error = sigaction1(l, SCARG(uap, signum), 179 SCARG(uap, nsa) ? &nbsa : 0, SCARG(uap, osa) ? &obsa : 0, 180 NULL, 0); 181 if (error) 182 return (error); 183 if (SCARG(uap, osa)) { 184 memset(&oesa, 0, sizeof(oesa)); 185 oesa.freebsd_sa_handler = obsa.sa_handler; 186 oesa.freebsd_sa_mask = obsa.sa_mask; 187 oesa.freebsd_sa_flags = obsa.sa_flags; 188 error = copyout(&oesa, SCARG(uap, osa), sizeof(oesa)); 189 if (error) 190 return (error); 191 } 192 return (0); 193 } 194 195 int 196 freebsd_sys_utrace(struct lwp *l, const struct freebsd_sys_utrace_args *uap, register_t *retval) 197 { 198 /* { 199 syscallarg(void *) addr; 200 syscallarg(size_t) len; 201 } */ 202 203 return ktruser("FreeBSD utrace", SCARG(uap, addr), SCARG(uap, len), 204 0); 205 } 206