1 /* $NetBSD: compat_mod.c,v 1.9 2009/11/22 19:09:16 mbalmer Exp $ */
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software developed for The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Linkage for the compat module: spaghetti.
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: compat_mod.c,v 1.9 2009/11/22 19:09:16 mbalmer Exp $");
40 #include "opt_compat_netbsd.h"
41 #include "opt_compat_43.h"
47 #include <sys/systm.h>
48 #include <sys/module.h>
49 #include <sys/rwlock.h>
51 #include <sys/signalvar.h>
52 #include <sys/sched.h> /* for cpuset_t */
53 #include <sys/syscall.h>
54 #include <sys/syscallargs.h>
55 #include <sys/syscallvar.h>
57 #include <uvm/uvm_extern.h>
58 #include <uvm/uvm_object.h>
60 #include <compat/common/compat_util.h>
62 MODULE(MODULE_CLASS_MISC
, compat
, NULL
);
64 int ttcompat(struct tty
*, u_long
, void *, int, struct lwp
*);
67 extern char sigcode
[], esigcode
[];
68 struct uvm_object
*emul_netbsd_object
;
71 extern krwlock_t exec_lock
;
72 extern krwlock_t ttcompat_lock
;
74 static const struct syscall_package compat_syscalls
[] = {
75 #if defined(COMPAT_43)
76 { SYS_compat_43_fstat43
, 0, (sy_call_t
*)compat_43_sys_fstat
},
77 { SYS_compat_43_lstat43
, 0, (sy_call_t
*)compat_43_sys_lstat
},
78 { SYS_compat_43_oaccept
, 0, (sy_call_t
*)compat_43_sys_accept
},
79 { SYS_compat_43_ocreat
, 0, (sy_call_t
*)compat_43_sys_creat
},
80 { SYS_compat_43_oftruncate
, 0, (sy_call_t
*)compat_43_sys_ftruncate
},
81 { SYS_compat_43_ogetdirentries
, 0, (sy_call_t
*)compat_43_sys_getdirentries
},
82 { SYS_compat_43_ogetdtablesize
, 0, (sy_call_t
*)compat_43_sys_getdtablesize
},
83 { SYS_compat_43_ogethostid
, 0, (sy_call_t
*)compat_43_sys_gethostid
},
84 { SYS_compat_43_ogethostname
, 0, (sy_call_t
*)compat_43_sys_gethostname
},
85 { SYS_compat_43_ogetkerninfo
, 0, (sy_call_t
*)compat_43_sys_getkerninfo
},
86 { SYS_compat_43_ogetpagesize
, 0, (sy_call_t
*)compat_43_sys_getpagesize
},
87 { SYS_compat_43_ogetpeername
, 0, (sy_call_t
*)compat_43_sys_getpeername
},
88 { SYS_compat_43_ogetrlimit
, 0, (sy_call_t
*)compat_43_sys_getrlimit
},
89 { SYS_compat_43_ogetsockname
, 0, (sy_call_t
*)compat_43_sys_getsockname
},
90 { SYS_compat_43_okillpg
, 0, (sy_call_t
*)compat_43_sys_killpg
},
91 { SYS_compat_43_olseek
, 0, (sy_call_t
*)compat_43_sys_lseek
},
92 { SYS_compat_43_ommap
, 0, (sy_call_t
*)compat_43_sys_mmap
},
93 { SYS_compat_43_oquota
, 0, (sy_call_t
*)compat_43_sys_quota
},
94 { SYS_compat_43_orecv
, 0, (sy_call_t
*)compat_43_sys_recv
},
95 { SYS_compat_43_orecvfrom
, 0, (sy_call_t
*)compat_43_sys_recvfrom
},
96 { SYS_compat_43_orecvmsg
, 0, (sy_call_t
*)compat_43_sys_recvmsg
},
97 { SYS_compat_43_osend
, 0, (sy_call_t
*)compat_43_sys_send
},
98 { SYS_compat_43_osendmsg
, 0, (sy_call_t
*)compat_43_sys_sendmsg
},
99 { SYS_compat_43_osethostid
, 0, (sy_call_t
*)compat_43_sys_sethostid
},
100 { SYS_compat_43_osethostname
, 0, (sy_call_t
*)compat_43_sys_sethostname
},
101 { SYS_compat_43_osetrlimit
, 0, (sy_call_t
*)compat_43_sys_setrlimit
},
102 { SYS_compat_43_osigblock
, 0, (sy_call_t
*)compat_43_sys_sigblock
},
103 { SYS_compat_43_osigsetmask
, 0, (sy_call_t
*)compat_43_sys_sigsetmask
},
104 { SYS_compat_43_osigstack
, 0, (sy_call_t
*)compat_43_sys_sigstack
},
105 { SYS_compat_43_osigvec
, 0, (sy_call_t
*)compat_43_sys_sigvec
},
106 { SYS_compat_43_otruncate
, 0, (sy_call_t
*)compat_43_sys_truncate
},
107 { SYS_compat_43_owait
, 0, (sy_call_t
*)compat_43_sys_wait
},
108 { SYS_compat_43_stat43
, 0, (sy_call_t
*)compat_43_sys_stat
},
111 #if defined(COMPAT_09)
112 { SYS_compat_09_ogetdomainname
, 0, (sy_call_t
*)compat_09_sys_getdomainname
},
113 { SYS_compat_09_osetdomainname
, 0, (sy_call_t
*)compat_09_sys_setdomainname
},
114 { SYS_compat_09_ouname
, 0, (sy_call_t
*)compat_09_sys_uname
},
117 #if defined(COMPAT_10) && !defined(_LP64)
118 # if defined(SYSVMSG)
119 { SYS_compat_10_omsgsys
, 0, (sy_call_t
*)compat_10_sys_msgsys
},
121 # if defined(SYSVSEM)
122 { SYS_compat_10_osemsys
, 0, (sy_call_t
*)compat_10_sys_semsys
},
124 # if defined(SYSVSHM)
125 { SYS_compat_10_oshmsys
, 0, (sy_call_t
*)compat_10_sys_shmsys
},
127 #endif /* defined(COMPAT_10) && !defined(_LP64) */
129 #if defined(COMPAT_12)
130 { SYS_compat_12_fstat12
, 0, (sy_call_t
*)compat_12_sys_fstat
},
131 { SYS_compat_12_getdirentries
, 0, (sy_call_t
*)compat_12_sys_getdirentries
},
132 { SYS_compat_12_lstat12
, 0, (sy_call_t
*)compat_12_sys_lstat
},
133 { SYS_compat_12_msync
, 0, (sy_call_t
*)compat_12_sys_msync
},
134 { SYS_compat_12_oreboot
, 0, (sy_call_t
*)compat_12_sys_reboot
},
135 { SYS_compat_12_oswapon
, 0, (sy_call_t
*)compat_12_sys_swapon
},
136 { SYS_compat_12_stat12
, 0, (sy_call_t
*)compat_12_sys_stat
},
139 #if defined(COMPAT_13)
140 { SYS_compat_13_sigaction13
, 0, (sy_call_t
*)compat_13_sys_sigaction
},
141 { SYS_compat_13_sigaltstack13
, 0, (sy_call_t
*)compat_13_sys_sigaltstack
},
142 { SYS_compat_13_sigpending13
, 0, (sy_call_t
*)compat_13_sys_sigpending
},
143 { SYS_compat_13_sigprocmask13
, 0, (sy_call_t
*)compat_13_sys_sigprocmask
},
144 { SYS_compat_13_sigreturn13
, 0, (sy_call_t
*)compat_13_sys_sigreturn
},
145 { SYS_compat_13_sigsuspend13
, 0, (sy_call_t
*)compat_13_sys_sigsuspend
},
148 #if defined(COMPAT_14)
149 # if defined(SYSVSEM)
150 { SYS_compat_14___semctl
, 0, (sy_call_t
*)compat_14_sys___semctl
},
152 # if defined(SYSVMSG)
153 { SYS_compat_14_msgctl
, 0, (sy_call_t
*)compat_14_sys_msgctl
},
155 # if defined(SYSVSHM)
156 { SYS_compat_14_shmctl
, 0, (sy_call_t
*)compat_14_sys_shmctl
},
160 #if defined(COMPAT_16)
161 { SYS_compat_16___sigaction14
, 0, (sy_call_t
*)compat_16_sys___sigaction14
},
162 { SYS_compat_16___sigreturn14
, 0, (sy_call_t
*)compat_16_sys___sigreturn14
},
165 #if defined(COMPAT_20)
166 { SYS_compat_20_fhstatfs
, 0, (sy_call_t
*)compat_20_sys_fhstatfs
},
167 { SYS_compat_20_fstatfs
, 0, (sy_call_t
*)compat_20_sys_fstatfs
},
168 { SYS_compat_20_getfsstat
, 0, (sy_call_t
*)compat_20_sys_getfsstat
},
169 { SYS_compat_20_statfs
, 0, (sy_call_t
*)compat_20_sys_statfs
},
172 #if defined(COMPAT_30)
173 { SYS_compat_30___fhstat30
, 0, (sy_call_t
*)compat_30_sys___fhstat30
},
174 { SYS_compat_30___fstat13
, 0, (sy_call_t
*)compat_30_sys___fstat13
},
175 { SYS_compat_30___lstat13
, 0, (sy_call_t
*)compat_30_sys___lstat13
},
176 { SYS_compat_30___stat13
, 0, (sy_call_t
*)compat_30_sys___stat13
},
177 { SYS_compat_30_fhopen
, 0, (sy_call_t
*)compat_30_sys_fhopen
},
178 { SYS_compat_30_fhstat
, 0, (sy_call_t
*)compat_30_sys_fhstat
},
179 { SYS_compat_30_fhstatvfs1
, 0, (sy_call_t
*)compat_30_sys_fhstatvfs1
},
180 { SYS_compat_30_getdents
, 0, (sy_call_t
*)compat_30_sys_getdents
},
181 { SYS_compat_30_getfh
, 0, (sy_call_t
*)compat_30_sys_getfh
},
182 { SYS_compat_30_socket
, 0, (sy_call_t
*)compat_30_sys_socket
},
185 #if defined(COMPAT_40)
186 { SYS_compat_40_mount
, 0, (sy_call_t
*)compat_40_sys_mount
},
188 #if defined(COMPAT_50)
189 { SYS_compat_50_wait4
, 0, (sy_call_t
*)compat_50_sys_wait4
},
190 { SYS_compat_50_mknod
, 0, (sy_call_t
*)compat_50_sys_mknod
},
191 { SYS_compat_50_setitimer
, 0, (sy_call_t
*)compat_50_sys_setitimer
},
192 { SYS_compat_50_getitimer
, 0, (sy_call_t
*)compat_50_sys_getitimer
},
193 { SYS_compat_50_select
, 0, (sy_call_t
*)compat_50_sys_select
},
194 { SYS_compat_50_gettimeofday
, 0, (sy_call_t
*)compat_50_sys_gettimeofday
},
195 { SYS_compat_50_getrusage
, 0, (sy_call_t
*)compat_50_sys_getrusage
},
196 { SYS_compat_50_settimeofday
, 0, (sy_call_t
*)compat_50_sys_settimeofday
},
197 { SYS_compat_50_utimes
, 0, (sy_call_t
*)compat_50_sys_utimes
},
198 { SYS_compat_50_adjtime
, 0, (sy_call_t
*)compat_50_sys_adjtime
},
200 { SYS_compat_50_lfs_segwait
, 0, (sy_call_t
*)compat_50_sys_lfs_segwait
},
202 { SYS_compat_50_futimes
, 0, (sy_call_t
*)compat_50_sys_futimes
},
203 { SYS_compat_50_clock_gettime
, 0, (sy_call_t
*)compat_50_sys_clock_gettime
},
204 { SYS_compat_50_clock_settime
, 0, (sy_call_t
*)compat_50_sys_clock_settime
},
205 { SYS_compat_50_clock_getres
, 0, (sy_call_t
*)compat_50_sys_clock_getres
},
206 { SYS_compat_50_timer_settime
, 0, (sy_call_t
*)compat_50_sys_timer_settime
},
207 { SYS_compat_50_timer_gettime
, 0, (sy_call_t
*)compat_50_sys_timer_gettime
},
208 { SYS_compat_50_nanosleep
, 0, (sy_call_t
*)compat_50_sys_nanosleep
},
209 { SYS_compat_50___sigtimedwait
, 0, (sy_call_t
*)compat_50_sys___sigtimedwait
},
210 { SYS_compat_50_mq_timedsend
, 0, (sy_call_t
*)compat_50_sys_mq_timedsend
},
211 { SYS_compat_50_mq_timedreceive
, 0, (sy_call_t
*)compat_50_sys_mq_timedreceive
},
212 { SYS_compat_50_lutimes
, 0, (sy_call_t
*)compat_50_sys_lutimes
},
213 # if defined(SYSVSEM)
214 { SYS_compat_50_____semctl13
, 0, (sy_call_t
*)compat_50_sys_____semctl13
},
216 # if defined(SYSVMSG)
217 { SYS_compat_50___msgctl13
, 0, (sy_call_t
*)compat_50_sys___msgctl13
},
219 # if defined(SYSVSHM)
220 { SYS_compat_50___shmctl13
, 0, (sy_call_t
*)compat_50_sys___shmctl13
},
222 { SYS_compat_50__lwp_park
, 0, (sy_call_t
*)compat_50_sys__lwp_park
},
223 { SYS_compat_50_kevent
, 0, (sy_call_t
*)compat_50_sys_kevent
},
224 { SYS_compat_50_pselect
, 0, (sy_call_t
*)compat_50_sys_pselect
},
225 { SYS_compat_50_pollts
, 0, (sy_call_t
*)compat_50_sys_pollts
},
226 { SYS_compat_50___stat30
, 0, (sy_call_t
*)compat_50_sys___stat30
},
227 { SYS_compat_50___fstat30
, 0, (sy_call_t
*)compat_50_sys___fstat30
},
228 { SYS_compat_50___lstat30
, 0, (sy_call_t
*)compat_50_sys___lstat30
},
230 { SYS_compat_50___ntp_gettime30
, 0, (sy_call_t
*)compat_50_sys___ntp_gettime30
},
232 { SYS_compat_50___fhstat40
, 0, (sy_call_t
*)compat_50_sys___fhstat40
},
233 { SYS_compat_50_aio_suspend
, 0, (sy_call_t
*)compat_50_sys_aio_suspend
},
239 compat_modcmd(modcmd_t cmd
, void *arg
)
247 case MODULE_CMD_INIT
:
248 error
= syscall_establish(NULL
, compat_syscalls
);
253 KASSERT(ttcompatvec
== NULL
);
254 ttcompatvec
= ttcompat
;
257 KASSERT(emul_netbsd
.e_sigobject
== NULL
);
258 rw_enter(&exec_lock
, RW_WRITER
);
259 emul_netbsd
.e_sigcode
= sigcode
;
260 emul_netbsd
.e_esigcode
= esigcode
;
261 emul_netbsd
.e_sigobject
= &emul_netbsd_object
;
263 KASSERT(sendsig_sigcontext_vec
== NULL
);
264 sendsig_sigcontext_vec
= sendsig_sigcontext
;
266 #if defined(COMPAT_09) || defined(COMPAT_43)
267 compat_sysctl_init();
271 case MODULE_CMD_FINI
:
274 * Ensure sendsig_sigcontext() is not being used.
275 * module_lock prevents the flag being set on any
276 * further processes while we are here. See
277 * sigaction1() for the opposing half.
279 mutex_enter(proc_lock
);
280 PROCLIST_FOREACH(p
, &allproc
) {
281 if ((p
->p_lflag
& PL_SIGCOMPAT
) != 0) {
285 mutex_exit(proc_lock
);
290 /* Unlink the system calls. */
291 error
= syscall_disestablish(NULL
, compat_syscalls
);
296 /* Unlink ttcompatvec. */
297 if (rw_tryenter(&ttcompat_lock
, RW_WRITER
)) {
299 rw_exit(&ttcompat_lock
);
301 error
= syscall_establish(NULL
, compat_syscalls
);
308 * The sigobject may persist if still in use, but
309 * is reference counted so will die eventually.
311 rw_enter(&exec_lock
, RW_WRITER
);
312 if (emul_netbsd_object
!= NULL
) {
313 (*emul_netbsd_object
->pgops
->pgo_detach
)
314 (emul_netbsd_object
);
316 emul_netbsd_object
= NULL
;
317 emul_netbsd
.e_sigcode
= NULL
;
318 emul_netbsd
.e_esigcode
= NULL
;
319 emul_netbsd
.e_sigobject
= NULL
;
321 #endif /* COMPAT_16 */
322 #if defined(COMPAT_09) || defined(COMPAT_43)
323 compat_sysctl_fini();