netbsd32_compat_43.c revision 1.57 1 /* $NetBSD: netbsd32_compat_43.c,v 1.57 2019/01/27 02:08:40 pgoyette Exp $ */
2
3 /*
4 * Copyright (c) 1998, 2001 Matthew R. Green
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 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.57 2019/01/27 02:08:40 pgoyette Exp $");
31
32 #if defined(_KERNEL_OPT)
33 #include "opt_compat_43.h"
34 #endif
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/module.h>
39 #include <sys/fcntl.h>
40 #include <sys/filedesc.h>
41 #include <sys/mbuf.h>
42 #include <sys/mount.h>
43 #include <sys/namei.h>
44 #include <sys/socket.h>
45 #include <sys/proc.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
48 #include <sys/stat.h>
49 #include <sys/syscallvar.h>
50 #include <sys/syscallargs.h>
51 #include <sys/time.h>
52 #include <sys/ucred.h>
53 #include <sys/vfs_syscalls.h>
54 #include <uvm/uvm_extern.h>
55 #include <sys/sysctl.h>
56 #include <sys/swap.h>
57
58 #include <compat/netbsd32/netbsd32.h>
59 #include <compat/netbsd32/netbsd32_syscall.h>
60 #include <compat/netbsd32/netbsd32_syscallargs.h>
61
62 #include <compat/sys/stat.h>
63 #include <compat/sys/signal.h>
64 #include <compat/sys/signalvar.h>
65 #include <compat/sys/socket.h>
66
67 #define SYS_DEF(foo) struct foo##_args; \
68 int foo(struct lwp *, const struct foo##_args *, register_t *)
69
70 SYS_DEF(compat_43_netbsd32_sethostid);
71 SYS_DEF(compat_43_netbsd32_killpg);
72 SYS_DEF(compat_43_netbsd32_sigblock);
73 SYS_DEF(compat_43_netbsd32_sigsetmask);
74 #undef SYS_DEF
75
76 static void
77 netbsd32_from_stat(const struct stat *sb, struct netbsd32_stat43 *sp32)
78 {
79
80 sp32->st_dev = sb->st_dev;
81 sp32->st_ino = sb->st_ino;
82 sp32->st_mode = sb->st_mode;
83 sp32->st_nlink = sb->st_nlink;
84 sp32->st_uid = sb->st_uid;
85 sp32->st_gid = sb->st_gid;
86 sp32->st_rdev = sb->st_rdev;
87 sp32->st_size = sb->st_size < (quad_t)1 << 32 ? sb->st_size : -2;
88 sp32->st_atimespec.tv_sec = sb->st_atimespec.tv_sec;
89 sp32->st_atimespec.tv_nsec = sb->st_atimespec.tv_nsec;
90 sp32->st_mtimespec.tv_sec = sb->st_mtimespec.tv_sec;
91 sp32->st_mtimespec.tv_nsec = sb->st_mtimespec.tv_nsec;
92 sp32->st_ctimespec.tv_sec = sb->st_ctimespec.tv_sec;
93 sp32->st_ctimespec.tv_nsec = sb->st_ctimespec.tv_nsec;
94 sp32->st_blksize = sb->st_blksize;
95 sp32->st_blocks = sb->st_blocks;
96 sp32->st_flags = sb->st_flags;
97 sp32->st_gen = sb->st_gen;
98 }
99
100 /* file system syscalls */
101 int
102 compat_43_netbsd32_ocreat(struct lwp *l, const struct compat_43_netbsd32_ocreat_args *uap, register_t *retval)
103 {
104 /* {
105 syscallarg(const netbsd32_charp) path;
106 syscallarg(mode_t) mode;
107 } */
108 struct sys_open_args ua;
109
110 NETBSD32TOP_UAP(path, const char);
111 NETBSD32TO64_UAP(mode);
112 SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC;
113
114 return (sys_open(l, &ua, retval));
115 }
116
117 int
118 compat_43_netbsd32_olseek(struct lwp *l, const struct compat_43_netbsd32_olseek_args *uap, register_t *retval)
119 {
120 /* {
121 syscallarg(int) fd;
122 syscallarg(netbsd32_long) offset;
123 syscallarg(int) whence;
124 } */
125 struct sys_lseek_args ua;
126
127 SCARG(&ua, fd) = SCARG(uap, fd);
128 NETBSD32TOX_UAP(offset, long);
129 NETBSD32TO64_UAP(whence);
130 /* Maybe offsets > 2^32 should generate an error ? */
131 return sys_lseek(l, &ua, retval);
132 }
133
134 int
135 compat_43_netbsd32_stat43(struct lwp *l, const struct compat_43_netbsd32_stat43_args *uap, register_t *retval)
136 {
137 /* {
138 syscallarg(const netbsd32_charp) path;
139 syscallarg(netbsd32_stat43p_t) ub;
140 } */
141 struct stat sb;
142 struct netbsd32_stat43 sb32;
143 int error;
144
145 error = do_sys_stat(SCARG_P32(uap, path), FOLLOW, &sb);
146 if (error == 0) {
147 netbsd32_from_stat(&sb, &sb32);
148 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
149 }
150 return error;
151 }
152
153 int
154 compat_43_netbsd32_lstat43(struct lwp *l, const struct compat_43_netbsd32_lstat43_args *uap, register_t *retval)
155 {
156 /* {
157 syscallarg(const netbsd32_charp) path;
158 syscallarg(netbsd32_stat43p_t) ub;
159 } */
160 struct stat sb;
161 struct netbsd32_stat43 sb32;
162 int error;
163
164 error = do_sys_stat(SCARG_P32(uap, path), NOFOLLOW, &sb);
165 if (error == 0) {
166 netbsd32_from_stat(&sb, &sb32);
167 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
168 }
169 return error;
170 }
171
172 int
173 compat_43_netbsd32_fstat43(struct lwp *l, const struct compat_43_netbsd32_fstat43_args *uap, register_t *retval)
174 {
175 /* {
176 syscallarg(int) fd;
177 syscallarg(netbsd32_stat43p_t) sb;
178 } */
179 struct stat sb;
180 struct netbsd32_stat43 sb32;
181 int error;
182
183 error = do_sys_fstat(SCARG(uap, fd), &sb);
184 if (error == 0) {
185 netbsd32_from_stat(&sb, &sb32);
186 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32));
187 }
188 return error;
189 }
190
191 int
192 compat_43_netbsd32_otruncate(struct lwp *l, const struct compat_43_netbsd32_otruncate_args *uap, register_t *retval)
193 {
194 /* {
195 syscallarg(const netbsd32_charp) path;
196 syscallarg(netbsd32_long) length;
197 } */
198 struct sys_truncate_args ua;
199
200 NETBSD32TOP_UAP(path, const char);
201 NETBSD32TO64_UAP(length);
202 return (sys_truncate(l, &ua, retval));
203 }
204
205 int
206 compat_43_netbsd32_oftruncate(struct lwp *l, const struct compat_43_netbsd32_oftruncate_args *uap, register_t *retval)
207 {
208 /* {
209 syscallarg(int) fd;
210 syscallarg(netbsd32_long) length;
211 } */
212 struct sys_ftruncate_args ua;
213
214 NETBSD32TO64_UAP(fd);
215 NETBSD32TO64_UAP(length);
216 return (sys_ftruncate(l, &ua, retval));
217 }
218
219 int
220 compat_43_netbsd32_ogetdirentries(struct lwp *l, const struct compat_43_netbsd32_ogetdirentries_args *uap, register_t *retval)
221 {
222 /* {
223 syscallarg(int) fd;
224 syscallarg(netbsd32_charp) buf;
225 syscallarg(u_int) count;
226 syscallarg(netbsd32_longp) basep;
227 } */
228 struct compat_43_sys_getdirentries_args ua;
229
230 NETBSD32TO64_UAP(fd);
231 NETBSD32TOP_UAP(buf, char);
232 NETBSD32TO64_UAP(count);
233 NETBSD32TOP_UAP(basep, long);
234 return (compat_43_sys_getdirentries(l, &ua, retval));
235 }
236
237 /* kernel syscalls */
238 int
239 compat_43_netbsd32_ogetkerninfo(struct lwp *l, const struct compat_43_netbsd32_ogetkerninfo_args *uap, register_t *retval)
240 {
241 /* {
242 syscallarg(int) op;
243 syscallarg(netbsd32_charp) where;
244 syscallarg(netbsd32_intp) size;
245 syscallarg(int) arg;
246 } */
247 struct compat_43_sys_getkerninfo_args ua;
248
249 NETBSD32TO64_UAP(op);
250 NETBSD32TOP_UAP(where, char);
251 NETBSD32TOP_UAP(size, int);
252 NETBSD32TO64_UAP(arg);
253 return (compat_43_sys_getkerninfo(l, &ua, retval));
254 }
255
256 int
257 compat_43_netbsd32_ogethostname(struct lwp *l, const struct compat_43_netbsd32_ogethostname_args *uap, register_t *retval)
258 {
259 /* {
260 syscallarg(netbsd32_charp) hostname;
261 syscallarg(u_int) len;
262 } */
263 int name[2];
264 size_t sz;
265
266 name[0] = CTL_KERN;
267 name[1] = KERN_HOSTNAME;
268 sz = SCARG(uap, len);
269 return (old_sysctl(&name[0], 2,
270 SCARG_P32(uap, hostname), &sz, 0, 0, l));
271 }
272
273 int
274 compat_43_netbsd32_osethostname(struct lwp *l, const struct compat_43_netbsd32_osethostname_args *uap, register_t *retval)
275 {
276 /* {
277 syscallarg(netbsd32_charp) hostname;
278 syscallarg(u_int) len;
279 } */
280 int name[2];
281
282 name[0] = CTL_KERN;
283 name[1] = KERN_HOSTNAME;
284 return old_sysctl(&name[0], 2, 0, 0, (char *)SCARG_P32(uap,
285 hostname), SCARG(uap, len), l);
286 }
287
288 int
289 compat_43_netbsd32_sethostid(struct lwp *l, const struct compat_43_netbsd32_sethostid_args *uap, register_t *retval)
290 {
291 /* {
292 syscallarg(int32_t) hostid;
293 } */
294 struct compat_43_sys_sethostid_args ua;
295
296 NETBSD32TO64_UAP(hostid);
297 return (compat_43_sys_sethostid(l, &ua, retval));
298 }
299
300 int
301 compat_43_netbsd32_ogetrlimit(struct lwp *l, const struct compat_43_netbsd32_ogetrlimit_args *uap, register_t *retval)
302 {
303 /* {
304 syscallarg(int) which;
305 syscallarg(netbsd32_orlimitp_t) rlp;
306 } */
307 struct compat_43_sys_getrlimit_args ua;
308
309 NETBSD32TO64_UAP(which);
310 NETBSD32TOP_UAP(rlp, struct orlimit);
311 return (compat_43_sys_getrlimit(l, &ua, retval));
312 }
313
314 int
315 compat_43_netbsd32_osetrlimit(struct lwp *l, const struct compat_43_netbsd32_osetrlimit_args *uap, register_t *retval)
316 {
317 /* {
318 syscallarg(int) which;
319 syscallarg(netbsd32_orlimitp_t) rlp;
320 } */
321 struct compat_43_sys_setrlimit_args ua;
322
323 NETBSD32TO64_UAP(which);
324 NETBSD32TOP_UAP(rlp, struct orlimit);
325 return (compat_43_sys_setrlimit(l, &ua, retval));
326 }
327
328 int
329 compat_43_netbsd32_killpg(struct lwp *l, const struct compat_43_netbsd32_killpg_args *uap, register_t *retval)
330 {
331 /* {
332 syscallarg(int) pgid;
333 syscallarg(int) signum;
334 } */
335 struct compat_43_sys_killpg_args ua;
336
337 NETBSD32TO64_UAP(pgid);
338 NETBSD32TO64_UAP(signum);
339 return (compat_43_sys_killpg(l, &ua, retval));
340 }
341
342 /* virtual memory syscalls */
343 int
344 compat_43_netbsd32_ommap(struct lwp *l, const struct compat_43_netbsd32_ommap_args *uap, register_t *retval)
345 {
346 /* {
347 syscallarg(netbsd32_voidp) addr;
348 syscallarg(netbsd32_size_t) len;
349 syscallarg(int) prot;
350 syscallarg(int) flags;
351 syscallarg(int) fd;
352 syscallarg(netbsd32_long) pos;
353 } */
354 struct compat_43_sys_mmap_args ua;
355
356 NETBSD32TOP_UAP(addr, void *);
357 NETBSD32TOX_UAP(len, size_t);
358 NETBSD32TO64_UAP(prot);
359 NETBSD32TO64_UAP(flags);
360 NETBSD32TO64_UAP(fd);
361 NETBSD32TOX_UAP(pos, long);
362 return (compat_43_sys_mmap(l, &ua, retval));
363 }
364
365 /* network syscalls */
366 int
367 compat_43_netbsd32_oaccept(struct lwp *l, const struct compat_43_netbsd32_oaccept_args *uap, register_t *retval)
368 {
369 /* {
370 syscallarg(int) s;
371 syscallarg(netbsd32_voidp) name;
372 syscallarg(netbsd32_intp) anamelen;
373 } */
374 struct compat_43_sys_accept_args ua;
375
376 NETBSD32TOX_UAP(s, int);
377 NETBSD32TOP_UAP(name, void *);
378 NETBSD32TOP_UAP(anamelen, int);
379 return (compat_43_sys_accept(l, &ua, retval));
380 }
381
382 int
383 compat_43_netbsd32_osend(struct lwp *l, const struct compat_43_netbsd32_osend_args *uap, register_t *retval)
384 {
385 /* {
386 syscallarg(int) s;
387 syscallarg(netbsd32_voidp) buf;
388 syscallarg(int) len;
389 syscallarg(int) flags;
390 } */
391 struct compat_43_sys_send_args ua;
392
393 NETBSD32TO64_UAP(s);
394 NETBSD32TOP_UAP(buf, void *);
395 NETBSD32TO64_UAP(len);
396 NETBSD32TO64_UAP(flags);
397 return (compat_43_sys_send(l, &ua, retval));
398 }
399
400 int
401 compat_43_netbsd32_orecv(struct lwp *l, const struct compat_43_netbsd32_orecv_args *uap, register_t *retval)
402 {
403 /* {
404 syscallarg(int) s;
405 syscallarg(netbsd32_voidp) buf;
406 syscallarg(int) len;
407 syscallarg(int) flags;
408 } */
409 struct compat_43_sys_recv_args ua;
410
411 NETBSD32TO64_UAP(s);
412 NETBSD32TOP_UAP(buf, void *);
413 NETBSD32TO64_UAP(len);
414 NETBSD32TO64_UAP(flags);
415 return (compat_43_sys_recv(l, &ua, retval));
416 }
417
418 /*
419 * This is a brutal clone of compat_43_sys_recvmsg().
420 */
421 int
422 compat_43_netbsd32_orecvmsg(struct lwp *l, const struct compat_43_netbsd32_orecvmsg_args *uap, register_t *retval)
423 {
424 /* {
425 syscallarg(int) s;
426 syscallarg(netbsd32_omsghdrp_t) msg;
427 syscallarg(int) flags;
428 } */
429 struct netbsd32_omsghdr omsg;
430 struct msghdr msg;
431 struct mbuf *from, *control;
432 struct iovec *iov, aiov[UIO_SMALLIOV];
433 int error;
434
435 error = copyin(SCARG_P32(uap, msg), &omsg, sizeof (struct omsghdr));
436 if (error)
437 return (error);
438
439 if (NETBSD32PTR64(omsg.msg_accrights) == NULL)
440 omsg.msg_accrightslen = 0;
441 /* it was this way in 4.4BSD */
442 if (omsg.msg_accrightslen > MLEN)
443 return EINVAL;
444
445 iov = netbsd32_get_iov(NETBSD32PTR64(omsg.msg_iov), omsg.msg_iovlen,
446 aiov, __arraycount(aiov));
447 if (iov == NULL)
448 return EFAULT;
449
450 msg.msg_name = NETBSD32PTR64(omsg.msg_name);
451 msg.msg_namelen = omsg.msg_namelen;
452 msg.msg_iovlen = omsg.msg_iovlen;
453 msg.msg_iov = iov;
454 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
455
456 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
457 NETBSD32PTR64(omsg.msg_accrights) != NULL ? &control : NULL,
458 retval);
459 if (error != 0)
460 goto out;
461
462 /*
463 * If there is any control information and it's SCM_RIGHTS,
464 * pass it back to the program.
465 * XXX: maybe there can be more than one chunk of control data?
466 */
467 if (NETBSD32PTR64(omsg.msg_accrights) != NULL && control != NULL) {
468 struct cmsghdr *cmsg = mtod(control, void *);
469
470 if (cmsg->cmsg_level == SOL_SOCKET
471 && cmsg->cmsg_type == SCM_RIGHTS
472 && cmsg->cmsg_len < omsg.msg_accrightslen
473 && copyout(CMSG_DATA(cmsg),
474 NETBSD32PTR64(omsg.msg_accrights),
475 cmsg->cmsg_len) == 0) {
476 omsg.msg_accrightslen = cmsg->cmsg_len;
477 free_control_mbuf(l, control, control->m_next);
478 } else {
479 omsg.msg_accrightslen = 0;
480 free_control_mbuf(l, control, control);
481 }
482 } else
483 omsg.msg_accrightslen = 0;
484
485 if (from != NULL)
486 /* convert from sockaddr sa_family to osockaddr one here */
487 mtod(from, struct osockaddr *)->sa_family =
488 mtod(from, struct sockaddr *)->sa_family;
489
490 error = copyout_sockname(NETBSD32PTR64(omsg.msg_name),
491 &omsg.msg_namelen, 0, from);
492 if (from != NULL)
493 m_free(from);
494
495 if (error != 0)
496 error = copyout(&omsg, SCARG_P32(uap, msg), sizeof(omsg));
497 out:
498 if (iov != aiov) {
499 kmem_free(iov, omsg.msg_iovlen * sizeof(*iov));
500 }
501 return error;
502 }
503
504 int
505 compat_43_netbsd32_osendmsg(struct lwp *l, const struct compat_43_netbsd32_osendmsg_args *uap, register_t *retval)
506 {
507 /* {
508 syscallarg(int) s;
509 syscallarg(netbsd32_voidp) msg;
510 syscallarg(int) flags;
511 } */
512 struct iovec *iov, aiov[UIO_SMALLIOV];
513 struct netbsd32_omsghdr omsg;
514 struct msghdr msg;
515 struct mbuf *nam;
516 struct osockaddr *osa;
517 struct sockaddr *sa;
518 int error;
519
520 error = copyin(SCARG_P32(uap, msg), &omsg, sizeof (struct omsghdr));
521 if (error != 0)
522 return (error);
523
524 iov = netbsd32_get_iov(NETBSD32PTR64(omsg.msg_iov), omsg.msg_iovlen,
525 aiov, __arraycount(aiov));
526 if (iov == NULL)
527 return EFAULT;
528
529 msg.msg_iovlen = omsg.msg_iovlen;
530 msg.msg_iov = iov;
531 msg.msg_flags = MSG_NAMEMBUF;
532
533 error = sockargs(&nam, NETBSD32PTR64(omsg.msg_name), omsg.msg_namelen,
534 UIO_USERSPACE, MT_SONAME);
535 if (error != 0)
536 goto out;
537
538 sa = mtod(nam, void *);
539 osa = mtod(nam, void *);
540 sa->sa_family = osa->sa_family;
541 sa->sa_len = omsg.msg_namelen;
542
543 msg.msg_name = nam;
544 msg.msg_namelen = omsg.msg_namelen;
545 error = compat43_set_accrights(&msg, NETBSD32PTR64(omsg.msg_accrights),
546 omsg.msg_accrightslen);
547 if (error != 0) {
548 m_free(nam);
549 goto out;
550 }
551
552 error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
553 retval);
554
555 out:
556 if (iov != aiov)
557 kmem_free(iov, omsg.msg_iovlen * sizeof(*iov));
558 return (error);
559 }
560
561 int
562 compat_43_netbsd32_orecvfrom(struct lwp *l, const struct compat_43_netbsd32_orecvfrom_args *uap, register_t *retval)
563 {
564 /* {
565 syscallarg(int) s;
566 syscallarg(netbsd32_voidp) buf;
567 syscallarg(netbsd32_size_t) len;
568 syscallarg(int) flags;
569 syscallarg(netbsd32_voidp) from;
570 syscallarg(netbsd32_intp) fromlenaddr;
571 } */
572 struct compat_43_sys_recvfrom_args ua;
573
574 NETBSD32TO64_UAP(s);
575 NETBSD32TOP_UAP(buf, void *);
576 NETBSD32TOX_UAP(len, size_t);
577 NETBSD32TO64_UAP(flags);
578 NETBSD32TOP_UAP(from, void *);
579 NETBSD32TOP_UAP(fromlenaddr, int);
580 return (compat_43_sys_recvfrom(l, &ua, retval));
581 }
582
583 int
584 compat_43_netbsd32_ogetsockname(struct lwp *l, const struct compat_43_netbsd32_ogetsockname_args *uap, register_t *retval)
585 {
586 /* {
587 syscallarg(int) fdec;
588 syscallarg(netbsd32_voidp) asa;
589 syscallarg(netbsd32_intp) alen;
590 } */
591 struct compat_43_sys_getsockname_args ua;
592
593 NETBSD32TO64_UAP(fdec);
594 NETBSD32TOP_UAP(asa, void *);
595 NETBSD32TOP_UAP(alen, int *);
596 return (compat_43_sys_getsockname(l, &ua, retval));
597 }
598
599 int
600 compat_43_netbsd32_ogetpeername(struct lwp *l, const struct compat_43_netbsd32_ogetpeername_args *uap, register_t *retval)
601 {
602 /* {
603 syscallarg(int) fdes;
604 syscallarg(netbsd32_voidp) asa;
605 syscallarg(netbsd32_intp) alen;
606 } */
607 struct compat_43_sys_getpeername_args ua;
608
609 NETBSD32TO64_UAP(fdes);
610 NETBSD32TOP_UAP(asa, void *);
611 NETBSD32TOP_UAP(alen, int *);
612 return (compat_43_sys_getpeername(l, &ua, retval));
613 }
614
615 /* signal syscalls */
616 int
617 compat_43_netbsd32_osigvec(struct lwp *l, const struct compat_43_netbsd32_osigvec_args *uap, register_t *retval)
618 {
619 /* {
620 syscallarg(int) signum;
621 syscallarg(netbsd32_sigvecp_t) nsv;
622 syscallarg(netbsd32_sigvecp_t) osv;
623 } */
624 struct netbsd32_sigvec sv32;
625 struct sigaction nsa, osa;
626 int error;
627
628 if (SCARG(uap, signum) >= 32)
629 return EINVAL;
630
631 if (SCARG_P32(uap, nsv)) {
632 error = copyin(SCARG_P32(uap, nsv), &sv32, sizeof(sv32));
633 if (error)
634 return error;
635 nsa.sa_handler = NETBSD32PTR64(sv32.sv_handler);
636 nsa.sa_mask.__bits[0] = sv32.sv_mask;
637 nsa.sa_mask.__bits[1] = 0;
638 nsa.sa_mask.__bits[2] = 0;
639 nsa.sa_mask.__bits[3] = 0;
640 nsa.sa_flags = sv32.sv_flags ^ SA_RESTART;
641 error = sigaction1(l, SCARG(uap, signum), &nsa, &osa, NULL, 0);
642 } else
643 error = sigaction1(l, SCARG(uap, signum), NULL, &osa, NULL, 0);
644 if (error)
645 return error;
646
647 if (SCARG_P32(uap, osv)) {
648 NETBSD32PTR32(sv32.sv_handler, osa.sa_handler);
649 sv32.sv_mask = osa.sa_mask.__bits[0];
650 sv32.sv_flags = osa.sa_flags ^ SA_RESTART;
651 error = copyout(&sv32, SCARG_P32(uap, osv), sizeof(sv32));
652 }
653
654 return error;
655 }
656
657 int
658 compat_43_netbsd32_sigblock(struct lwp *l, const struct compat_43_netbsd32_sigblock_args *uap, register_t *retval)
659 {
660 /* {
661 syscallarg(int) mask;
662 } */
663 struct compat_43_sys_sigblock_args ua;
664
665 NETBSD32TO64_UAP(mask);
666 return (compat_43_sys_sigblock(l, &ua, retval));
667 }
668
669 int
670 compat_43_netbsd32_sigsetmask(struct lwp *l, const struct compat_43_netbsd32_sigsetmask_args *uap, register_t *retval)
671 {
672 /* {
673 syscallarg(int) mask;
674 } */
675 struct compat_43_sys_sigsetmask_args ua;
676
677 NETBSD32TO64_UAP(mask);
678 return (compat_43_sys_sigsetmask(l, &ua, retval));
679 }
680
681 int
682 compat_43_netbsd32_osigstack(struct lwp *l, const struct compat_43_netbsd32_osigstack_args *uap, register_t *retval)
683 {
684 /* {
685 syscallarg(netbsd32_sigstackp_t) nss;
686 syscallarg(netbsd32_sigstackp_t) oss;
687 } */
688 struct netbsd32_sigstack ss32;
689 struct sigaltstack nsa, osa;
690 int error;
691
692 if (SCARG_P32(uap, nss)) {
693 error = copyin(SCARG_P32(uap, nss), &ss32, sizeof(ss32));
694 if (error)
695 return error;
696 nsa.ss_sp = NETBSD32PTR64(ss32.ss_sp);
697 nsa.ss_size = SIGSTKSZ; /* Use the recommended size */
698 nsa.ss_flags = ss32.ss_onstack ? SS_ONSTACK : 0;
699 error = sigaltstack1(l, &nsa, &osa);
700 } else
701 error = sigaltstack1(l, NULL, &osa);
702 if (error)
703 return error;
704
705 if (SCARG_P32(uap, oss)) {
706 NETBSD32PTR32(ss32.ss_sp, osa.ss_sp);
707 ss32.ss_onstack = (osa.ss_flags & SS_ONSTACK) != 0;
708 error = copyout(&ss32, SCARG_P32(uap, oss), sizeof(ss32));
709 }
710
711 return error;
712 }
713
714 static struct syscall_package compat_netbsd32_43_syscalls[] = {
715 { NETBSD32_SYS_compat_43_netbsd32_ocreat, 0,
716 (sy_call_t *)compat_43_netbsd32_ocreat },
717 { NETBSD32_SYS_compat_43_netbsd32_olseek, 0,
718 (sy_call_t *)compat_43_netbsd32_olseek },
719 { NETBSD32_SYS_compat_43_netbsd32_stat43, 0,
720 (sy_call_t *)compat_43_netbsd32_stat43 },
721 { NETBSD32_SYS_compat_43_netbsd32_lstat43, 0,
722 (sy_call_t *)compat_43_netbsd32_lstat43 },
723 { NETBSD32_SYS_compat_43_netbsd32_fstat43, 0,
724 (sy_call_t *)compat_43_netbsd32_fstat43 },
725 { NETBSD32_SYS_compat_43_netbsd32_otruncate, 0,
726 (sy_call_t *)compat_43_netbsd32_otruncate },
727 { NETBSD32_SYS_compat_43_netbsd32_oftruncate, 0,
728 (sy_call_t *)compat_43_netbsd32_oftruncate },
729 { NETBSD32_SYS_compat_43_netbsd32_ogetdirentries, 0,
730 (sy_call_t *)compat_43_netbsd32_ogetdirentries },
731 { NETBSD32_SYS_compat_43_netbsd32_ogetkerninfo, 0,
732 (sy_call_t *)compat_43_netbsd32_ogetkerninfo },
733 { NETBSD32_SYS_compat_43_netbsd32_ogethostname, 0,
734 (sy_call_t *)compat_43_netbsd32_ogethostname },
735 { NETBSD32_SYS_compat_43_netbsd32_osethostname, 0,
736 (sy_call_t *)compat_43_netbsd32_osethostname },
737 { NETBSD32_SYS_compat_43_netbsd32_sethostid, 0,
738 (sy_call_t *)compat_43_netbsd32_sethostid },
739 { NETBSD32_SYS_compat_43_netbsd32_ogetrlimit, 0,
740 (sy_call_t *)compat_43_netbsd32_ogetrlimit },
741 { NETBSD32_SYS_compat_43_netbsd32_osetrlimit, 0,
742 (sy_call_t *)compat_43_netbsd32_osetrlimit },
743 { NETBSD32_SYS_compat_43_netbsd32_killpg, 0,
744 (sy_call_t *)compat_43_netbsd32_killpg },
745 { NETBSD32_SYS_compat_43_netbsd32_ommap, 0,
746 (sy_call_t *)compat_43_netbsd32_ommap },
747 { NETBSD32_SYS_compat_43_netbsd32_oaccept, 0,
748 (sy_call_t *)compat_43_netbsd32_oaccept },
749 { NETBSD32_SYS_compat_43_netbsd32_osend, 0,
750 (sy_call_t *)compat_43_netbsd32_osend },
751 { NETBSD32_SYS_compat_43_netbsd32_orecv, 0,
752 (sy_call_t *)compat_43_netbsd32_orecv },
753 { NETBSD32_SYS_compat_43_netbsd32_orecvmsg, 0,
754 (sy_call_t *)compat_43_netbsd32_orecvmsg },
755 { NETBSD32_SYS_compat_43_netbsd32_osendmsg, 0,
756 (sy_call_t *)compat_43_netbsd32_osendmsg },
757 { NETBSD32_SYS_compat_43_netbsd32_orecvfrom, 0,
758 (sy_call_t *)compat_43_netbsd32_orecvfrom },
759 { NETBSD32_SYS_compat_43_netbsd32_ogetsockname, 0,
760 (sy_call_t *)compat_43_netbsd32_ogetsockname },
761 { NETBSD32_SYS_compat_43_netbsd32_ogetpeername, 0,
762 (sy_call_t *)compat_43_netbsd32_ogetpeername },
763 { NETBSD32_SYS_compat_43_netbsd32_osigvec, 0,
764 (sy_call_t *)compat_43_netbsd32_osigvec },
765 { NETBSD32_SYS_compat_43_netbsd32_sigblock, 0,
766 (sy_call_t *)compat_43_netbsd32_sigblock },
767 { NETBSD32_SYS_compat_43_netbsd32_sigsetmask, 0,
768 (sy_call_t *)compat_43_netbsd32_sigsetmask },
769 { NETBSD32_SYS_compat_43_netbsd32_osigstack, 0,
770 (sy_call_t *)compat_43_netbsd32_osigstack },
771 { 0, 0, NULL }
772 };
773
774 MODULE(MODULE_CLASS_EXEC, compat_netbsd32_43, "compat_netbsd32,compat_43");
775
776 static int
777 compat_netbsd32_43_modcmd(modcmd_t cmd, void *arg)
778 {
779
780 switch (cmd) {
781 case MODULE_CMD_INIT:
782 return syscall_establish(&emul_netbsd32,
783 compat_netbsd32_43_syscalls);
784
785 case MODULE_CMD_FINI:
786 return syscall_disestablish(&emul_netbsd32,
787 compat_netbsd32_43_syscalls);
788
789 default:
790 return ENOTTY;
791 }
792 }
793