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