1 /*	$NetBSD: netbsd32_compat_43.c,v 1.23 2002/10/23 13:16:42 scw 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  * 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,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.23 2002/10/23 13:16:42 scw Exp $");
33 
34 #if defined(_KERNEL_OPT)
35 #include "opt_compat_43.h"
36 #endif
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/fcntl.h>
41 #include <sys/malloc.h>
42 #include <sys/mount.h>
43 #include <sys/proc.h>
44 #include <sys/stat.h>
45 #include <sys/syscallargs.h>
46 #include <sys/time.h>
47 #include <sys/ucred.h>
48 #include <uvm/uvm_extern.h>
49 #include <sys/sysctl.h>
50 #include <sys/swap.h>
51 
52 #include <compat/netbsd32/netbsd32.h>
53 #include <compat/netbsd32/netbsd32_syscallargs.h>
54 
55 int compat_43_netbsd32_sethostid __P((struct proc *, void *, register_t *));
56 int compat_43_netbsd32_killpg __P((struct proc *, void *, register_t *retval));
57 int compat_43_netbsd32_sigblock __P((struct proc *, void *, register_t *retval));
58 int compat_43_netbsd32_sigblock __P((struct proc *, void *, register_t *retval));
59 int compat_43_netbsd32_sigsetmask __P((struct proc *, void *, register_t *retval));
60 
61 void
62 netbsd32_from_stat43(sp43, sp32)
63 	struct stat43 *sp43;
64 	struct netbsd32_stat43 *sp32;
65 {
66 
67 	sp32->st_dev = sp43->st_dev;
68 	sp32->st_ino = sp43->st_ino;
69 	sp32->st_mode = sp43->st_mode;
70 	sp32->st_nlink = sp43->st_nlink;
71 	sp32->st_uid = sp43->st_uid;
72 	sp32->st_gid = sp43->st_gid;
73 	sp32->st_rdev = sp43->st_rdev;
74 	sp32->st_size = sp43->st_size;
75 	sp32->st_atimespec.tv_sec = sp43->st_atimespec.tv_sec;
76 	sp32->st_atimespec.tv_nsec = sp43->st_atimespec.tv_nsec;
77 	sp32->st_mtimespec.tv_sec = sp43->st_mtimespec.tv_sec;
78 	sp32->st_mtimespec.tv_nsec = sp43->st_mtimespec.tv_nsec;
79 	sp32->st_ctimespec.tv_sec = sp43->st_ctimespec.tv_sec;
80 	sp32->st_ctimespec.tv_nsec = sp43->st_ctimespec.tv_nsec;
81 	sp32->st_blksize = sp43->st_blksize;
82 	sp32->st_blocks = sp43->st_blocks;
83 	sp32->st_flags = sp43->st_flags;
84 	sp32->st_gen = sp43->st_gen;
85 }
86 
87 /* file system syscalls */
88 int
89 compat_43_netbsd32_ocreat(p, v, retval)
90 	struct proc *p;
91 	void *v;
92 	register_t *retval;
93 {
94 	struct compat_43_netbsd32_ocreat_args /* {
95 		syscallarg(const netbsd32_charp) path;
96 		syscallarg(mode_t) mode;
97 	} */ *uap = v;
98 	struct sys_open_args  ua;
99 	caddr_t sg;
100 
101 	NETBSD32TOP_UAP(path, const char);
102 	NETBSD32TO64_UAP(mode);
103 	SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC;
104 	sg = stackgap_init(p, 0);
105 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
106 
107 	return (sys_open(p, &ua, retval));
108 }
109 
110 int
111 compat_43_netbsd32_olseek(p, v, retval)
112 	struct proc *p;
113 	void *v;
114 	register_t *retval;
115 {
116 	struct compat_43_netbsd32_olseek_args /* {
117 		syscallarg(int) fd;
118 		syscallarg(netbsd32_long) offset;
119 		syscallarg(int) whence;
120 	} */ *uap = v;
121 	struct sys_lseek_args ua;
122 	int rv;
123 	off_t rt;
124 
125 	SCARG(&ua, fd) = SCARG(uap, fd);
126 	NETBSD32TOX_UAP(offset, long);
127 	NETBSD32TO64_UAP(whence);
128 	rv = sys_lseek(p, &ua, (register_t *)&rt);
129 	*retval = rt;
130 
131 	return (rv);
132 }
133 
134 int
135 compat_43_netbsd32_stat43(p, v, retval)
136 	struct proc *p;
137 	void *v;
138 	register_t *retval;
139 {
140 	struct compat_43_netbsd32_stat43_args /* {
141 		syscallarg(const netbsd32_charp) path;
142 		syscallarg(netbsd32_stat43p_t) ub;
143 	} */ *uap = v;
144 	struct stat43 sb43, *sgsbp;
145 	struct netbsd32_stat43 sb32;
146 	struct compat_43_sys_stat_args ua;
147 	caddr_t sg = stackgap_init(p, 0);
148 	int rv, error;
149 
150 	NETBSD32TOP_UAP(path, const char);
151 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43));
152 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
153 	rv = compat_43_sys_stat(p, &ua, retval);
154 
155 	error = copyin(sgsbp, &sb43, sizeof(sb43));
156 	if (error)
157 		return error;
158 	netbsd32_from_stat43(&sb43, &sb32);
159 	error = copyout(&sb32, (char *)NETBSD32PTR64(SCARG(uap, ub)),
160 	    sizeof(sb32));
161 	if (error)
162 		return error;
163 
164 	return (rv);
165 }
166 
167 int
168 compat_43_netbsd32_lstat43(p, v, retval)
169 	struct proc *p;
170 	void *v;
171 	register_t *retval;
172 {
173 	struct compat_43_netbsd32_lstat43_args /* {
174 		syscallarg(const netbsd32_charp) path;
175 		syscallarg(netbsd32_stat43p_t) ub;
176 	} */ *uap = v;
177 	struct stat43 sb43, *sgsbp;
178 	struct netbsd32_stat43 sb32;
179 	struct compat_43_sys_lstat_args ua;
180 	caddr_t sg = stackgap_init(p, 0);
181 	int rv, error;
182 
183 	NETBSD32TOP_UAP(path, const char);
184 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43));
185 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
186 	rv = compat_43_sys_stat(p, &ua, retval);
187 
188 	error = copyin(sgsbp, &sb43, sizeof(sb43));
189 	if (error)
190 		return error;
191 	netbsd32_from_stat43(&sb43, &sb32);
192 	error = copyout(&sb32, (char *)NETBSD32PTR64(SCARG(uap, ub)),
193 	    sizeof(sb32));
194 	if (error)
195 		return error;
196 
197 	return (rv);
198 }
199 
200 int
201 compat_43_netbsd32_fstat43(p, v, retval)
202 	struct proc *p;
203 	void *v;
204 	register_t *retval;
205 {
206 	struct compat_43_netbsd32_fstat43_args /* {
207 		syscallarg(int) fd;
208 		syscallarg(netbsd32_stat43p_t) sb;
209 	} */ *uap = v;
210 	struct stat43 sb43, *sgsbp;
211 	struct netbsd32_stat43 sb32;
212 	struct compat_43_sys_fstat_args ua;
213 	caddr_t sg = stackgap_init(p, 0);
214 	int rv, error;
215 
216 	NETBSD32TO64_UAP(fd);
217 	SCARG(&ua, sb) = sgsbp = stackgap_alloc(p, &sg, sizeof(sb43));
218 	rv = compat_43_sys_fstat(p, &ua, retval);
219 
220 	error = copyin(sgsbp, &sb43, sizeof(sb43));
221 	if (error)
222 		return error;
223 	netbsd32_from_stat43(&sb43, &sb32);
224 	error = copyout(&sb32, (char *)NETBSD32PTR64(SCARG(uap, sb)),
225 	    sizeof(sb32));
226 	if (error)
227 		return error;
228 
229 	return (rv);
230 }
231 
232 int
233 compat_43_netbsd32_otruncate(p, v, retval)
234 	struct proc *p;
235 	void *v;
236 	register_t *retval;
237 {
238 	struct compat_43_netbsd32_otruncate_args /* {
239 		syscallarg(const netbsd32_charp) path;
240 		syscallarg(netbsd32_long) length;
241 	} */ *uap = v;
242 	struct sys_truncate_args ua;
243 
244 	NETBSD32TOP_UAP(path, const char);
245 	NETBSD32TO64_UAP(length);
246 	return (sys_ftruncate(p, &ua, retval));
247 }
248 
249 int
250 compat_43_netbsd32_oftruncate(p, v, retval)
251 	struct proc *p;
252 	void *v;
253 	register_t *retval;
254 {
255 	struct compat_43_netbsd32_oftruncate_args /* {
256 		syscallarg(int) fd;
257 		syscallarg(netbsd32_long) length;
258 	} */ *uap = v;
259 	struct sys_ftruncate_args ua;
260 
261 	NETBSD32TO64_UAP(fd);
262 	NETBSD32TO64_UAP(length);
263 	return (sys_ftruncate(p, &ua, retval));
264 }
265 
266 int
267 compat_43_netbsd32_ogetdirentries(p, v, retval)
268 	struct proc *p;
269 	void *v;
270 	register_t *retval;
271 {
272 	struct compat_43_netbsd32_ogetdirentries_args /* {
273 		syscallarg(int) fd;
274 		syscallarg(netbsd32_charp) buf;
275 		syscallarg(u_int) count;
276 		syscallarg(netbsd32_longp) basep;
277 	} */ *uap = v;
278 	struct compat_43_sys_getdirentries_args ua;
279 
280 	NETBSD32TO64_UAP(fd);
281 	NETBSD32TOP_UAP(buf, char);
282 	NETBSD32TO64_UAP(count);
283 	NETBSD32TOP_UAP(basep, long);
284 	return (compat_43_sys_getdirentries(p, &ua, retval));
285 }
286 
287 /* kernel syscalls */
288 int
289 compat_43_netbsd32_ogetkerninfo(p, v, retval)
290 	struct proc *p;
291 	void *v;
292 	register_t *retval;
293 {
294 	struct compat_43_netbsd32_ogetkerninfo_args /* {
295 		syscallarg(int) op;
296 		syscallarg(netbsd32_charp) where;
297 		syscallarg(netbsd32_intp) size;
298 		syscallarg(int) arg;
299 	} */ *uap = v;
300 	struct compat_43_sys_getkerninfo_args ua;
301 
302 	NETBSD32TO64_UAP(op);
303 	NETBSD32TOP_UAP(where, char);
304 	NETBSD32TOP_UAP(size, int);
305 	NETBSD32TO64_UAP(arg);
306 	return (compat_43_sys_getkerninfo(p, &ua, retval));
307 }
308 
309 int
310 compat_43_netbsd32_ogethostname(p, v, retval)
311 	struct proc *p;
312 	void *v;
313 	register_t *retval;
314 {
315 	struct compat_43_netbsd32_ogethostname_args /* {
316 		syscallarg(netbsd32_charp) hostname;
317 		syscallarg(u_int) len;
318 	} */ *uap = v;
319 	int name;
320 	size_t sz;
321 
322 	name = KERN_HOSTNAME;
323 	sz = SCARG(uap, len);
324 	return (kern_sysctl(&name, 1,
325 	    (char *)NETBSD32PTR64(SCARG(uap, hostname)), &sz, 0, 0, p));
326 }
327 
328 int
329 compat_43_netbsd32_osethostname(p, v, retval)
330 	struct proc *p;
331 	void *v;
332 	register_t *retval;
333 {
334 	struct compat_43_netbsd32_osethostname_args /* {
335 		syscallarg(netbsd32_charp) hostname;
336 		syscallarg(u_int) len;
337 	} */ *uap = v;
338 	int name;
339 	int error;
340 
341 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
342 		return (error);
343 	name = KERN_HOSTNAME;
344 	return (kern_sysctl(&name, 1, 0, 0, (char *)NETBSD32PTR64(SCARG(uap,
345 	    hostname)), SCARG(uap, len), p));
346 }
347 
348 int
349 compat_43_netbsd32_sethostid(p, v, retval)
350 	struct proc *p;
351 	void *v;
352 	register_t *retval;
353 {
354 	struct compat_43_netbsd32_sethostid_args /* {
355 		syscallarg(int32_t) hostid;
356 	} */ *uap = v;
357 	struct compat_43_sys_sethostid_args ua;
358 
359 	NETBSD32TO64_UAP(hostid);
360 	return (compat_43_sys_sethostid(p, &ua, retval));
361 }
362 
363 int
364 compat_43_netbsd32_ogetrlimit(p, v, retval)
365 	struct proc *p;
366 	void *v;
367 	register_t *retval;
368 {
369 	struct compat_43_netbsd32_ogetrlimit_args /* {
370 		syscallarg(int) which;
371 		syscallarg(netbsd32_orlimitp_t) rlp;
372 	} */ *uap = v;
373 	struct compat_43_sys_getrlimit_args ua;
374 
375 	NETBSD32TO64_UAP(which);
376 	NETBSD32TOP_UAP(rlp, struct orlimit);
377 	return (compat_43_sys_getrlimit(p, &ua, retval));
378 }
379 
380 int
381 compat_43_netbsd32_osetrlimit(p, v, retval)
382 	struct proc *p;
383 	void *v;
384 	register_t *retval;
385 {
386 	struct compat_43_netbsd32_osetrlimit_args /* {
387 		syscallarg(int) which;
388 		syscallarg(netbsd32_orlimitp_t) rlp;
389 	} */ *uap = v;
390 	struct compat_43_sys_setrlimit_args ua;
391 
392 	NETBSD32TO64_UAP(which);
393 	NETBSD32TOP_UAP(rlp, struct orlimit);
394 	return (compat_43_sys_setrlimit(p, &ua, retval));
395 }
396 
397 int
398 compat_43_netbsd32_killpg(p, v, retval)
399 	struct proc *p;
400 	void *v;
401 	register_t *retval;
402 {
403 	struct compat_43_netbsd32_killpg_args /* {
404 		syscallarg(int) pgid;
405 		syscallarg(int) signum;
406 	} */ *uap = v;
407 	struct compat_43_sys_killpg_args ua;
408 
409 	NETBSD32TO64_UAP(pgid);
410 	NETBSD32TO64_UAP(signum);
411 	return (compat_43_sys_killpg(p, &ua, retval));
412 }
413 
414 /* virtual memory syscalls */
415 int
416 compat_43_netbsd32_ommap(p, v, retval)
417 	struct proc *p;
418 	void *v;
419 	register_t *retval;
420 {
421 	struct compat_43_netbsd32_ommap_args /* {
422 		syscallarg(netbsd32_caddr_t) addr;
423 		syscallarg(netbsd32_size_t) len;
424 		syscallarg(int) prot;
425 		syscallarg(int) flags;
426 		syscallarg(int) fd;
427 		syscallarg(netbsd32_long) pos;
428 	} */ *uap = v;
429 	struct compat_43_sys_mmap_args ua;
430 
431 	NETBSD32TOX64_UAP(addr, caddr_t);
432 	NETBSD32TOX_UAP(len, size_t);
433 	NETBSD32TO64_UAP(prot);
434 	NETBSD32TO64_UAP(flags);
435 	NETBSD32TO64_UAP(fd);
436 	NETBSD32TOX_UAP(pos, long);
437 	return (compat_43_sys_mmap(p, &ua, retval));
438 }
439 
440 /* network syscalls */
441 int
442 compat_43_netbsd32_oaccept(p, v, retval)
443 	struct proc *p;
444 	void *v;
445 	register_t *retval;
446 {
447 	struct compat_43_netbsd32_oaccept_args /* {
448 		syscallarg(int) s;
449 		syscallarg(netbsd32_caddr_t) name;
450 		syscallarg(netbsd32_intp) anamelen;
451 	} */ *uap = v;
452 	struct compat_43_sys_accept_args ua;
453 
454 	NETBSD32TOX_UAP(s, int);
455 	NETBSD32TOX64_UAP(name, caddr_t);
456 	NETBSD32TOP_UAP(anamelen, int);
457 	return (compat_43_sys_accept(p, &ua, retval));
458 }
459 
460 int
461 compat_43_netbsd32_osend(p, v, retval)
462 	struct proc *p;
463 	void *v;
464 	register_t *retval;
465 {
466 	struct compat_43_netbsd32_osend_args /* {
467 		syscallarg(int) s;
468 		syscallarg(netbsd32_caddr_t) buf;
469 		syscallarg(int) len;
470 		syscallarg(int) flags;
471 	} */ *uap = v;
472 	struct compat_43_sys_send_args ua;
473 
474 	NETBSD32TO64_UAP(s);
475 	NETBSD32TOX64_UAP(buf, caddr_t);
476 	NETBSD32TO64_UAP(len);
477 	NETBSD32TO64_UAP(flags);
478 	return (compat_43_sys_send(p, &ua, retval));
479 }
480 
481 int
482 compat_43_netbsd32_orecv(p, v, retval)
483 	struct proc *p;
484 	void *v;
485 	register_t *retval;
486 {
487 	struct compat_43_netbsd32_orecv_args /* {
488 		syscallarg(int) s;
489 		syscallarg(netbsd32_caddr_t) buf;
490 		syscallarg(int) len;
491 		syscallarg(int) flags;
492 	} */ *uap = v;
493 	struct compat_43_sys_recv_args ua;
494 
495 	NETBSD32TO64_UAP(s);
496 	NETBSD32TOX64_UAP(buf, caddr_t);
497 	NETBSD32TO64_UAP(len);
498 	NETBSD32TO64_UAP(flags);
499 	return (compat_43_sys_recv(p, &ua, retval));
500 }
501 
502 /*
503  * XXX convert these to use a common iovec code to the native
504  * netbsd call.
505  */
506 int
507 compat_43_netbsd32_orecvmsg(p, v, retval)
508 	struct proc *p;
509 	void *v;
510 	register_t *retval;
511 {
512 	struct compat_43_netbsd32_orecvmsg_args /* {
513 		syscallarg(int) s;
514 		syscallarg(netbsd32_omsghdrp_t) msg;
515 		syscallarg(int) flags;
516 	} */ *uap = v;
517 	struct compat_43_sys_recvmsg_args ua;
518 	struct omsghdr omh, *sgsbp;
519 	struct netbsd32_omsghdr omh32;
520 	struct iovec iov, *sgsbp2;
521 	struct netbsd32_iovec iov32, *iovec32p;
522 	caddr_t sg = stackgap_init(p, 0);
523 	int i, error, rv;
524 
525 	NETBSD32TO64_UAP(s);
526 	NETBSD32TO64_UAP(flags);
527 
528 	/*
529 	 * this is annoying:
530 	 *	- copyin the msghdr32 struct
531 	 *	- stackgap_alloc a msghdr struct
532 	 *	- convert msghdr32 to msghdr:
533 	 *		- stackgap_alloc enough space for iovec's
534 	 *		- copy in each iov32, and convert to iov
535 	 *		- copyout converted iov
536 	 *	- copyout converted msghdr
537 	 *	- do real syscall
538 	 *	- copyin the msghdr struct
539 	 *	- convert msghdr to msghdr32
540 	 *		- copyin each iov and convert to iov32
541 	 *		- copyout converted iov32
542 	 *	- copyout converted msghdr32
543 	 */
544 	error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, msg)), &omh32,
545 	    sizeof(omh32));
546 	if (error)
547 		return (error);
548 
549 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh));
550 	omh.msg_name = (caddr_t)NETBSD32PTR64(omh32.msg_name);
551 	omh.msg_namelen = omh32.msg_namelen;
552 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
553 	omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen);
554 	iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov);
555 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
556 		error = copyin(iovec32p, &iov32, sizeof(iov32));
557 		if (error)
558 			return (error);
559 		iov.iov_base =
560 		    (struct iovec *)NETBSD32PTR64(iovec32p->iov_base);
561 		iov.iov_len = (size_t)iovec32p->iov_len;
562 		error = copyout(&iov, sgsbp2, sizeof(iov));
563 		if (error)
564 			return (error);
565 	}
566 	omh.msg_accrights = (caddr_t)NETBSD32PTR64(omh32.msg_accrights);
567 	omh.msg_accrightslen = omh32.msg_accrightslen;
568 	error = copyout(&omh, sgsbp, sizeof(omh));
569 	if (error)
570 		return (error);
571 
572 	rv = compat_43_sys_recvmsg(p, &ua, retval);
573 
574 	error = copyin(sgsbp, &omh, sizeof(omh));
575 	if (error)
576 		return error;
577 	omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name;
578 	omh32.msg_namelen = omh.msg_namelen;
579 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
580 	iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov);
581 	sgsbp2 = omh.msg_iov;
582 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
583 		error = copyin(sgsbp2, &iov, sizeof(iov));
584 		if (error)
585 			return (error);
586 		iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base;
587 		iov32.iov_len = (netbsd32_size_t)iov.iov_len;
588 		error = copyout(&iov32, iovec32p, sizeof(iov32));
589 		if (error)
590 			return (error);
591 	}
592 	omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights;
593 	omh32.msg_accrightslen = omh.msg_accrightslen;
594 
595 	error = copyout(&omh32, (char *)NETBSD32PTR64(SCARG(uap, msg)),
596 	    sizeof(omh32));
597 	if (error)
598 		return error;
599 
600 	return (rv);
601 }
602 
603 int
604 compat_43_netbsd32_osendmsg(p, v, retval)
605 	struct proc *p;
606 	void *v;
607 	register_t *retval;
608 {
609 	struct compat_43_netbsd32_osendmsg_args /* {
610 		syscallarg(int) s;
611 		syscallarg(netbsd32_caddr_t) msg;
612 		syscallarg(int) flags;
613 	} */ *uap = v;
614 	struct compat_43_sys_recvmsg_args ua;
615 	struct omsghdr omh, *sgsbp;
616 	struct netbsd32_omsghdr omh32;
617 	struct iovec iov, *sgsbp2;
618 	struct netbsd32_iovec iov32, *iovec32p;
619 	caddr_t sg = stackgap_init(p, 0);
620 	int i, error, rv;
621 
622 	NETBSD32TO64_UAP(s);
623 	NETBSD32TO64_UAP(flags);
624 
625 	/*
626 	 * this is annoying:
627 	 *	- copyin the msghdr32 struct
628 	 *	- stackgap_alloc a msghdr struct
629 	 *	- convert msghdr32 to msghdr:
630 	 *		- stackgap_alloc enough space for iovec's
631 	 *		- copy in each iov32, and convert to iov
632 	 *		- copyout converted iov
633 	 *	- copyout converted msghdr
634 	 *	- do real syscall
635 	 *	- copyin the msghdr struct
636 	 *	- convert msghdr to msghdr32
637 	 *		- copyin each iov and convert to iov32
638 	 *		- copyout converted iov32
639 	 *	- copyout converted msghdr32
640 	 */
641 	error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, msg)), &omh32,
642 	    sizeof(omh32));
643 	if (error)
644 		return (error);
645 
646 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(p, &sg, sizeof(omh));
647 	omh.msg_name = (caddr_t)NETBSD32PTR64(omh32.msg_name);
648 	omh.msg_namelen = omh32.msg_namelen;
649 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
650 	omh.msg_iov = sgsbp2 = stackgap_alloc(p, &sg, sizeof(struct iovec) * omh.msg_iovlen);
651 	iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov);
652 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
653 		error = copyin(iovec32p, &iov32, sizeof(iov32));
654 		if (error)
655 			return (error);
656 		iov.iov_base =
657 		    (struct iovec *)NETBSD32PTR64(iovec32p->iov_base);
658 		iov.iov_len = (size_t)iovec32p->iov_len;
659 		error = copyout(&iov, sgsbp2, sizeof(iov));
660 		if (error)
661 			return (error);
662 	}
663 	omh.msg_accrights = (caddr_t)NETBSD32PTR64(omh32.msg_accrights);
664 	omh.msg_accrightslen = omh32.msg_accrightslen;
665 	error = copyout(&omh, sgsbp, sizeof(omh));
666 	if (error)
667 		return (error);
668 
669 	rv = compat_43_sys_sendmsg(p, &ua, retval);
670 
671 	error = copyin(sgsbp, &omh, sizeof(omh));
672 	if (error)
673 		return error;
674 	omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name;
675 	omh32.msg_namelen = omh.msg_namelen;
676 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
677 	iovec32p = (struct netbsd32_iovec *)NETBSD32PTR64(omh32.msg_iov);
678 	sgsbp2 = omh.msg_iov;
679 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
680 		error = copyin(sgsbp2, &iov, sizeof(iov));
681 		if (error)
682 			return (error);
683 		iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base;
684 		iov32.iov_len = (netbsd32_size_t)iov.iov_len;
685 		error = copyout(&iov32, iovec32p, sizeof(iov32));
686 		if (error)
687 			return (error);
688 	}
689 	omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights;
690 	omh32.msg_accrightslen = omh.msg_accrightslen;
691 
692 	error = copyout(&omh32, (char *)NETBSD32PTR64(SCARG(uap, msg)),
693 	    sizeof(omh32));
694 	if (error)
695 		return error;
696 
697 	return (rv);
698 }
699 
700 int
701 compat_43_netbsd32_orecvfrom(p, v, retval)
702 	struct proc *p;
703 	void *v;
704 	register_t *retval;
705 {
706 	struct compat_43_netbsd32_orecvfrom_args /* {
707 		syscallarg(int) s;
708 		syscallarg(netbsd32_caddr_t) buf;
709 		syscallarg(netbsd32_size_t) len;
710 		syscallarg(int) flags;
711 		syscallarg(netbsd32_caddr_t) from;
712 		syscallarg(netbsd32_intp) fromlenaddr;
713 	} */ *uap = v;
714 	struct compat_43_sys_recvfrom_args ua;
715 
716 	NETBSD32TO64_UAP(s);
717 	NETBSD32TOX64_UAP(buf, caddr_t);
718 	NETBSD32TOX_UAP(len, size_t);
719 	NETBSD32TO64_UAP(flags);
720 	NETBSD32TOX64_UAP(from, caddr_t);
721 	NETBSD32TOP_UAP(fromlenaddr, int);
722 	return (compat_43_sys_recvfrom(p, &ua, retval));
723 }
724 
725 int
726 compat_43_netbsd32_ogetsockname(p, v, retval)
727 	struct proc *p;
728 	void *v;
729 	register_t *retval;
730 {
731 	struct compat_43_netbsd32_ogetsockname_args /* {
732 		syscallarg(int) fdec;
733 		syscallarg(netbsd32_caddr_t) asa;
734 		syscallarg(netbsd32_intp) alen;
735 	} */ *uap = v;
736 	struct compat_43_sys_getsockname_args ua;
737 
738 	NETBSD32TO64_UAP(fdec);
739 	NETBSD32TOX64_UAP(asa, caddr_t);
740 	NETBSD32TOP_UAP(alen, int);
741 	return (compat_43_sys_getsockname(p, &ua, retval));
742 }
743 
744 int
745 compat_43_netbsd32_ogetpeername(p, v, retval)
746 	struct proc *p;
747 	void *v;
748 	register_t *retval;
749 {
750 	struct compat_43_netbsd32_ogetpeername_args /* {
751 		syscallarg(int) fdes;
752 		syscallarg(netbsd32_caddr_t) asa;
753 		syscallarg(netbsd32_intp) alen;
754 	} */ *uap = v;
755 	struct compat_43_sys_getpeername_args ua;
756 
757 	NETBSD32TO64_UAP(fdes);
758 	NETBSD32TOX64_UAP(asa, caddr_t);
759 	NETBSD32TOP_UAP(alen, int);
760 	return (compat_43_sys_getpeername(p, &ua, retval));
761 }
762 
763 /* signal syscalls */
764 int
765 compat_43_netbsd32_osigvec(p, v, retval)
766 	struct proc *p;
767 	void *v;
768 	register_t *retval;
769 {
770 	struct compat_43_netbsd32_osigvec_args /* {
771 		syscallarg(int) signum;
772 		syscallarg(netbsd32_sigvecp_t) nsv;
773 		syscallarg(netbsd32_sigvecp_t) osv;
774 	} */ *uap = v;
775 	struct compat_43_sys_sigvec_args ua;
776 	struct netbsd32_sigvec sv32;
777 	struct sigvec sv, *sgnsvp, *sgosvp;
778 	caddr_t sg = stackgap_init(p, 0);
779 	int rv, error;
780 
781 	NETBSD32TO64_UAP(signum);
782 	if (SCARG(uap, osv))
783 		SCARG(&ua, osv) = sgosvp = stackgap_alloc(p, &sg, sizeof(sv));
784 	else
785 		SCARG(&ua, osv) = NULL;
786 	if (SCARG(uap, nsv)) {
787 		SCARG(&ua, nsv) = sgnsvp = stackgap_alloc(p, &sg, sizeof(sv));
788 		error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nsv)), &sv32,
789 		    sizeof(sv32));
790 		if (error)
791 			return (error);
792 		sv.sv_handler = (void *)NETBSD32PTR64(sv32.sv_handler);
793 		sv.sv_mask = sv32.sv_mask;
794 		sv.sv_flags = sv32.sv_flags;
795 		error = copyout(&sv, sgnsvp, sizeof(sv));
796 		if (error)
797 			return (error);
798 	} else
799 		SCARG(&ua, nsv) = NULL;
800 	rv = compat_43_sys_sigvec(p, &ua, retval);
801 	if (rv)
802 		return (rv);
803 
804 	if (SCARG(uap, osv)) {
805 		error = copyin(sgosvp, &sv, sizeof(sv));
806 		if (error)
807 			return (error);
808 		sv32.sv_handler = (netbsd32_sigvecp_t)(u_long)sv.sv_handler;
809 		sv32.sv_mask = sv.sv_mask;
810 		sv32.sv_flags = sv.sv_flags;
811 		error = copyout(&sv32, (caddr_t)NETBSD32PTR64(SCARG(uap, osv)),
812 		    sizeof(sv32));
813 		if (error)
814 			return (error);
815 	}
816 
817 	return (0);
818 }
819 
820 int
821 compat_43_netbsd32_sigblock(p, v, retval)
822 	struct proc *p;
823 	void *v;
824 	register_t *retval;
825 {
826 	struct compat_43_netbsd32_sigblock_args /* {
827 		syscallarg(int) mask;
828 	} */ *uap = v;
829 	struct compat_43_sys_sigblock_args ua;
830 
831 	NETBSD32TO64_UAP(mask);
832 	return (compat_43_sys_sigblock(p, &ua, retval));
833 }
834 
835 int
836 compat_43_netbsd32_sigsetmask(p, v, retval)
837 	struct proc *p;
838 	void *v;
839 	register_t *retval;
840 {
841 	struct compat_43_netbsd32_sigsetmask_args /* {
842 		syscallarg(int) mask;
843 	} */ *uap = v;
844 	struct compat_43_sys_sigsetmask_args ua;
845 
846 	NETBSD32TO64_UAP(mask);
847 	return (compat_43_sys_sigsetmask(p, &ua, retval));
848 }
849 
850 int
851 compat_43_netbsd32_osigstack(p, v, retval)
852 	struct proc *p;
853 	void *v;
854 	register_t *retval;
855 {
856 	struct compat_43_netbsd32_osigstack_args /* {
857 		syscallarg(netbsd32_sigstackp_t) nss;
858 		syscallarg(netbsd32_sigstackp_t) oss;
859 	} */ *uap = v;
860 	struct compat_43_sys_sigstack_args ua;
861 	struct netbsd32_sigstack ss32;
862 	struct sigstack ss, *sgossp, *sgnssp;
863 	caddr_t sg = stackgap_init(p, 0);
864 	int error, rv;
865 
866 	if (SCARG(uap, oss))
867 		SCARG(&ua, oss) = sgossp = stackgap_alloc(p, &sg, sizeof(ss));
868 	else
869 		SCARG(&ua, oss) = NULL;
870 	if (SCARG(uap, nss)) {
871 		SCARG(&ua, nss) = sgnssp = stackgap_alloc(p, &sg, sizeof(ss));
872 		error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nss)), &ss32,
873 		    sizeof(ss32));
874 		if (error)
875 			return (error);
876 		ss.ss_sp = (void *)NETBSD32PTR64(ss32.ss_sp);
877 		ss.ss_onstack = ss32.ss_onstack;
878 		error = copyout(&ss, sgnssp, sizeof(ss));
879 		if (error)
880 			return (error);
881 	} else
882 		SCARG(&ua, nss) = NULL;
883 
884 	rv = compat_43_sys_sigstack(p, &ua, retval);
885 	if (rv)
886 		return (rv);
887 
888 	if (SCARG(uap, oss)) {
889 		error = copyin(sgossp, &ss, sizeof(ss));
890 		if (error)
891 			return (error);
892 		ss32.ss_sp = (netbsd32_sigstackp_t)(u_long)ss.ss_sp;
893 		ss32.ss_onstack = ss.ss_onstack;
894 		error = copyout(&ss32, (caddr_t)NETBSD32PTR64(SCARG(uap, oss)),
895 		    sizeof(ss32));
896 		if (error)
897 			return (error);
898 	}
899 
900 	return (0);
901 }
902