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