freebsd32_misc.c revision 123744
155714Skris/*- 255714Skris * Copyright (c) 2002 Doug Rabson 355714Skris * All rights reserved. 455714Skris * 555714Skris * Redistribution and use in source and binary forms, with or without 655714Skris * modification, are permitted provided that the following conditions 755714Skris * are met: 8280304Sjkim * 1. Redistributions of source code must retain the above copyright 955714Skris * notice, this list of conditions and the following disclaimer. 1055714Skris * 2. Redistributions in binary form must reproduce the above copyright 1155714Skris * notice, this list of conditions and the following disclaimer in the 1255714Skris * documentation and/or other materials provided with the distribution. 1355714Skris * 1455714Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15280304Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1655714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1755714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1855714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1955714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2055714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2155714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22280304Sjkim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2355714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2455714Skris * SUCH DAMAGE. 2555714Skris */ 2655714Skris 2755714Skris#include <sys/cdefs.h> 2855714Skris__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 123744 2003-12-23 02:48:11Z peter $"); 2955714Skris 3055714Skris#include "opt_compat.h" 3155714Skris 3255714Skris#include <sys/param.h> 3355714Skris#include <sys/systm.h> 3455714Skris#include <sys/bus.h> 3555714Skris#include <sys/exec.h> 3655714Skris#include <sys/fcntl.h> 37280304Sjkim#include <sys/filedesc.h> 3855714Skris#include <sys/imgact.h> 3955714Skris#include <sys/kernel.h> 40280304Sjkim#include <sys/lock.h> 4155714Skris#include <sys/malloc.h> 4255714Skris#include <sys/file.h> /* Must come after sys/malloc.h */ 4355714Skris#include <sys/mman.h> 4455714Skris#include <sys/module.h> 4555714Skris#include <sys/mount.h> 4655714Skris#include <sys/mutex.h> 4755714Skris#include <sys/namei.h> 4855714Skris#include <sys/param.h> 4955714Skris#include <sys/proc.h> 5055714Skris#include <sys/reboot.h> 5155714Skris#include <sys/resource.h> 52280304Sjkim#include <sys/resourcevar.h> 5355714Skris#include <sys/selinfo.h> 5455714Skris#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 5555714Skris#include <sys/signal.h> 5655714Skris#include <sys/signalvar.h> 5755714Skris#include <sys/socket.h> 5855714Skris#include <sys/socketvar.h> 5955714Skris#include <sys/stat.h> 6055714Skris#include <sys/syscallsubr.h> 61238405Sjkim#include <sys/sysctl.h> 62109998Smarkm#include <sys/sysent.h> 6355714Skris#include <sys/sysproto.h> 64238405Sjkim#include <sys/systm.h> 6555714Skris#include <sys/unistd.h> 66280304Sjkim#include <sys/user.h> 67280304Sjkim#include <sys/utsname.h> 68238405Sjkim#include <sys/vnode.h> 6955714Skris 70109998Smarkm#include <vm/vm.h> 71280304Sjkim#include <vm/vm_kern.h> 72280304Sjkim#include <vm/vm_param.h> 73280304Sjkim#include <vm/pmap.h> 74109998Smarkm#include <vm/vm_map.h> 7555714Skris#include <vm/vm_object.h> 76238405Sjkim#include <vm/vm_extern.h> 77238405Sjkim 78280304Sjkim#include <compat/freebsd32/freebsd32_util.h> 79280304Sjkim#include <compat/freebsd32/freebsd32.h> 80238405Sjkim#include <compat/freebsd32/freebsd32_proto.h> 81280304Sjkim 82280304SjkimCTASSERT(sizeof(struct timeval32) == 8); 83280304SjkimCTASSERT(sizeof(struct timespec32) == 8); 84280304SjkimCTASSERT(sizeof(struct statfs32) == 256); 85280304SjkimCTASSERT(sizeof(struct rusage32) == 72); 86280304Sjkim 87238405Sjkimint 88238405Sjkimfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 89238405Sjkim{ 90280304Sjkim int error; 91280304Sjkim caddr_t sg; 92280304Sjkim struct rusage32 *rusage32, ru32; 93280304Sjkim struct rusage *rusage = NULL, ru; 94109998Smarkm 95238405Sjkim rusage32 = uap->rusage; 96280304Sjkim if (rusage32) { 97109998Smarkm sg = stackgap_init(); 98280304Sjkim rusage = stackgap_alloc(&sg, sizeof(struct rusage)); 9955714Skris uap->rusage = (struct rusage32 *)rusage; 100280304Sjkim } 101280304Sjkim error = wait4(td, (struct wait_args *)uap); 102280304Sjkim if (error) 103280304Sjkim return (error); 104280304Sjkim if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) { 105280304Sjkim TV_CP(ru, ru32, ru_utime); 106280304Sjkim TV_CP(ru, ru32, ru_stime); 107280304Sjkim CP(ru, ru32, ru_maxrss); 108280304Sjkim CP(ru, ru32, ru_ixrss); 109280304Sjkim CP(ru, ru32, ru_idrss); 110280304Sjkim CP(ru, ru32, ru_isrss); 111280304Sjkim CP(ru, ru32, ru_minflt); 112109998Smarkm CP(ru, ru32, ru_majflt); 11355714Skris CP(ru, ru32, ru_nswap); 11455714Skris CP(ru, ru32, ru_inblock); 115142425Snectar CP(ru, ru32, ru_oublock); 116280304Sjkim CP(ru, ru32, ru_msgsnd); 117280304Sjkim CP(ru, ru32, ru_msgrcv); 118280304Sjkim CP(ru, ru32, ru_nsignals); 119280304Sjkim CP(ru, ru32, ru_nvcsw); 120280304Sjkim CP(ru, ru32, ru_nivcsw); 121280304Sjkim error = copyout(&ru32, rusage32, sizeof(ru32)); 122280304Sjkim } 123142425Snectar return (error); 12455714Skris} 125280304Sjkim 126280304Sjkimstatic void 127280304Sjkimcopy_statfs(struct statfs *in, struct statfs32 *out) 128238405Sjkim{ 129238405Sjkim CP(*in, *out, f_bsize); 130238405Sjkim CP(*in, *out, f_iosize); 131280304Sjkim CP(*in, *out, f_blocks); 132238405Sjkim CP(*in, *out, f_bfree); 133280304Sjkim CP(*in, *out, f_bavail); 134280304Sjkim CP(*in, *out, f_files); 135280304Sjkim CP(*in, *out, f_ffree); 136238405Sjkim CP(*in, *out, f_fsid); 137280304Sjkim CP(*in, *out, f_owner); 138238405Sjkim CP(*in, *out, f_type); 139280304Sjkim CP(*in, *out, f_flags); 140280304Sjkim CP(*in, *out, f_flags); 141280304Sjkim CP(*in, *out, f_syncwrites); 142280304Sjkim CP(*in, *out, f_asyncwrites); 143280304Sjkim bcopy(in->f_fstypename, 144280304Sjkim out->f_fstypename, MFSNAMELEN); 145280304Sjkim bcopy(in->f_mntonname, 146280304Sjkim out->f_mntonname, MNAMELEN); 147280304Sjkim CP(*in, *out, f_syncreads); 148280304Sjkim CP(*in, *out, f_asyncreads); 149280304Sjkim bcopy(in->f_mntfromname, 150280304Sjkim out->f_mntfromname, MNAMELEN); 151238405Sjkim} 152280304Sjkim 153280304Sjkimint 154280304Sjkimfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap) 155280304Sjkim{ 156280304Sjkim int error; 157280304Sjkim caddr_t sg; 158280304Sjkim struct statfs32 *sp32, stat32; 159280304Sjkim struct statfs *sp = NULL, stat; 160280304Sjkim int maxcount, count, i; 161280304Sjkim 162280304Sjkim sp32 = uap->buf; 163238405Sjkim maxcount = uap->bufsize / sizeof(struct statfs32); 164280304Sjkim 165280304Sjkim if (sp32) { 166280304Sjkim sg = stackgap_init(); 167280304Sjkim sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 168280304Sjkim uap->buf = (struct statfs32 *)sp; 169238405Sjkim } 170280304Sjkim error = getfsstat(td, (struct getfsstat_args *) uap); 171280304Sjkim if (sp32 && !error) { 172280304Sjkim count = td->td_retval[0]; 173280304Sjkim for (i = 0; i < count; i++) { 174280304Sjkim error = copyin(&sp[i], &stat, sizeof(stat)); 175238405Sjkim if (error) 176280304Sjkim return (error); 177238405Sjkim copy_statfs(&stat, &stat32); 178280304Sjkim error = copyout(&stat32, &sp32[i], sizeof(stat32)); 179238405Sjkim if (error) 180280304Sjkim return (error); 181280304Sjkim } 182280304Sjkim } 183280304Sjkim return (error); 184280304Sjkim} 185280304Sjkim 186280304Sjkimstruct sigaltstack32 { 187280304Sjkim u_int32_t ss_sp; 188280304Sjkim u_int32_t ss_size; 189238405Sjkim int ss_flags; 190280304Sjkim}; 191238405Sjkim 192280304SjkimCTASSERT(sizeof(struct sigaltstack32) == 12); 193238405Sjkim 194280304Sjkimint 195238405Sjkimfreebsd32_sigaltstack(struct thread *td, 196280304Sjkim struct freebsd32_sigaltstack_args *uap) 197280304Sjkim{ 198238405Sjkim struct sigaltstack32 s32; 199238405Sjkim struct sigaltstack ss, oss, *ssp; 200238405Sjkim int error; 201280304Sjkim 202280304Sjkim if (uap->ss != NULL) { 203280304Sjkim error = copyin(uap->ss, &s32, sizeof(s32)); 204280304Sjkim if (error) 205280304Sjkim return (error); 206280304Sjkim PTRIN_CP(s32, ss, ss_sp); 207238405Sjkim CP(s32, ss, ss_size); 208280304Sjkim CP(s32, ss, ss_flags); 209280304Sjkim ssp = &ss; 210280304Sjkim } else 211280304Sjkim ssp = NULL; 212280304Sjkim error = kern_sigaltstack(td, ssp, &oss); 213280304Sjkim if (error == 0 && uap->oss != NULL) { 214280304Sjkim PTROUT_CP(oss, s32, ss_sp); 215280304Sjkim CP(oss, s32, ss_size); 216280304Sjkim CP(oss, s32, ss_flags); 217280304Sjkim error = copyout(&s32, uap->oss, sizeof(s32)); 218280304Sjkim } 219280304Sjkim return (error); 220280304Sjkim} 221238405Sjkim 222280304Sjkimint 223238405Sjkimfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 224280304Sjkim{ 225238405Sjkim int error; 226280304Sjkim caddr_t sg; 227280304Sjkim struct execve_args ap; 228280304Sjkim u_int32_t *p32, arg; 229280304Sjkim char **p, *p64; 230280304Sjkim int count; 231238405Sjkim 232280304Sjkim sg = stackgap_init(); 233280304Sjkim ap.fname = uap->fname; 234280304Sjkim 235238405Sjkim if (uap->argv) { 236280304Sjkim count = 0; 237280304Sjkim p32 = uap->argv; 238238405Sjkim do { 239280304Sjkim error = copyin(p32++, &arg, sizeof(arg)); 240280304Sjkim if (error) 241280304Sjkim return error; 242280304Sjkim count++; 243280304Sjkim } while (arg != 0); 244280304Sjkim p = stackgap_alloc(&sg, count * sizeof(char *)); 245238405Sjkim ap.argv = p; 246280304Sjkim p32 = uap->argv; 247280304Sjkim do { 248280304Sjkim error = copyin(p32++, &arg, sizeof(arg)); 249280304Sjkim if (error) 250280304Sjkim return error; 251280304Sjkim p64 = PTRIN(arg); 252238405Sjkim error = copyout(&p64, p++, sizeof(p64)); 253280304Sjkim if (error) 254238405Sjkim return error; 255280304Sjkim } while (arg != 0); 256280304Sjkim } 257280304Sjkim if (uap->envv) { 258280304Sjkim count = 0; 259280304Sjkim p32 = uap->envv; 260280304Sjkim do { 261280304Sjkim error = copyin(p32++, &arg, sizeof(arg)); 262280304Sjkim if (error) 263280304Sjkim return error; 264280304Sjkim count++; 265280304Sjkim } while (arg != 0); 266280304Sjkim p = stackgap_alloc(&sg, count * sizeof(char *)); 267280304Sjkim ap.envv = p; 268280304Sjkim p32 = uap->envv; 269280304Sjkim do { 270280304Sjkim error = copyin(p32++, &arg, sizeof(arg)); 271238405Sjkim if (error) 272280304Sjkim return error; 273280304Sjkim p64 = PTRIN(arg); 274238405Sjkim error = copyout(&p64, p++, sizeof(p64)); 275280304Sjkim if (error) 276280304Sjkim return error; 277280304Sjkim } while (arg != 0); 278280304Sjkim } 279280304Sjkim 280238405Sjkim return execve(td, &ap); 281280304Sjkim} 282280304Sjkim 283280304Sjkim#ifdef __ia64__ 284280304Sjkimstatic int 285280304Sjkimfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 286280304Sjkim int prot, int fd, off_t pos) 287280304Sjkim{ 288280304Sjkim vm_map_t map; 289280304Sjkim vm_map_entry_t entry; 290280304Sjkim int rv; 291280304Sjkim 292280304Sjkim map = &td->td_proc->p_vmspace->vm_map; 293280304Sjkim if (fd != -1) 294280304Sjkim prot |= VM_PROT_WRITE; 295280304Sjkim 296280304Sjkim if (vm_map_lookup_entry(map, start, &entry)) { 297238405Sjkim if ((entry->protection & prot) != prot) { 298238405Sjkim rv = vm_map_protect(map, 299238405Sjkim trunc_page(start), 300238405Sjkim round_page(end), 301280304Sjkim entry->protection | prot, 302280304Sjkim FALSE); 303280304Sjkim if (rv != KERN_SUCCESS) 304280304Sjkim return (EINVAL); 305280304Sjkim } 306280304Sjkim } else { 307280304Sjkim vm_offset_t addr = trunc_page(start); 308280304Sjkim rv = vm_map_find(map, 0, 0, 309280304Sjkim &addr, PAGE_SIZE, FALSE, prot, 310280304Sjkim VM_PROT_ALL, 0); 311280304Sjkim if (rv != KERN_SUCCESS) 312280304Sjkim return (EINVAL); 313280304Sjkim } 314280304Sjkim 315280304Sjkim if (fd != -1) { 316280304Sjkim struct pread_args r; 317238405Sjkim r.fd = fd; 318280304Sjkim r.buf = (void *) start; 319280304Sjkim r.nbyte = end - start; 320238405Sjkim r.offset = pos; 321280304Sjkim return (pread(td, &r)); 322280304Sjkim } else { 323238405Sjkim while (start < end) { 324280304Sjkim subyte((void *) start, 0); 325280304Sjkim start++; 326280304Sjkim } 327280304Sjkim return (0); 328280304Sjkim } 329280304Sjkim} 330280304Sjkim#endif 331280304Sjkim 332238405Sjkimint 333280304Sjkimfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 334280304Sjkim{ 335238405Sjkim struct mmap_args ap; 336238405Sjkim vm_offset_t addr = (vm_offset_t) uap->addr; 337280304Sjkim vm_size_t len = uap->len; 338280304Sjkim int prot = uap->prot; 339280304Sjkim int flags = uap->flags; 340109998Smarkm int fd = uap->fd; 34155714Skris off_t pos = (uap->poslo 342109998Smarkm | ((off_t)uap->poshi << 32)); 343280304Sjkim#ifdef __ia64__ 344109998Smarkm vm_size_t pageoff; 345280304Sjkim int error; 346109998Smarkm 347280304Sjkim /* 348109998Smarkm * Attempt to handle page size hassles. 34955714Skris */ 350280304Sjkim pageoff = (pos & PAGE_MASK); 351280304Sjkim if (flags & MAP_FIXED) { 352280304Sjkim vm_offset_t start, end; 353280304Sjkim start = addr; 354280304Sjkim end = addr + len; 355280304Sjkim 35655714Skris if (start != trunc_page(start)) { 357109998Smarkm error = freebsd32_mmap_partial(td, start, 358109998Smarkm round_page(start), prot, 359280304Sjkim fd, pos); 360280304Sjkim if (fd != -1) 361280304Sjkim pos += round_page(start) - start; 362280304Sjkim start = round_page(start); 363280304Sjkim } 364280304Sjkim if (end != round_page(end)) { 365280304Sjkim vm_offset_t t = trunc_page(end); 366280304Sjkim error = freebsd32_mmap_partial(td, t, end, 367280304Sjkim prot, fd, 368280304Sjkim pos + t - start); 369109998Smarkm end = trunc_page(end); 370109998Smarkm } 371238405Sjkim if (end > start && fd != -1 && (pos & PAGE_MASK)) { 372280304Sjkim /* 373280304Sjkim * We can't map this region at all. The specified 374280304Sjkim * address doesn't have the same alignment as the file 375280304Sjkim * position. Fake the mapping by simply reading the 376280304Sjkim * entire region into memory. First we need to make 377238405Sjkim * sure the region exists. 378238405Sjkim */ 379280304Sjkim vm_map_t map; 380280304Sjkim struct pread_args r; 381280304Sjkim int rv; 382280304Sjkim 383280304Sjkim prot |= VM_PROT_WRITE; 384280304Sjkim map = &td->td_proc->p_vmspace->vm_map; 385238405Sjkim rv = vm_map_remove(map, start, end); 386238405Sjkim if (rv != KERN_SUCCESS) 387280304Sjkim return (EINVAL); 388280304Sjkim rv = vm_map_find(map, 0, 0, 389280304Sjkim &start, end - start, FALSE, 390280304Sjkim prot, VM_PROT_ALL, 0); 391280304Sjkim if (rv != KERN_SUCCESS) 392280304Sjkim return (EINVAL); 393280304Sjkim r.fd = fd; 394238405Sjkim r.buf = (void *) start; 395238405Sjkim r.nbyte = end - start; 396280304Sjkim r.offset = pos; 397280304Sjkim error = pread(td, &r); 398280304Sjkim if (error) 399280304Sjkim return (error); 400238405Sjkim 401238405Sjkim td->td_retval[0] = addr; 402280304Sjkim return (0); 403280304Sjkim } 404280304Sjkim if (end == start) { 405238405Sjkim /* 406280304Sjkim * After dealing with the ragged ends, there 407280304Sjkim * might be none left. 408280304Sjkim */ 409280304Sjkim td->td_retval[0] = addr; 410280304Sjkim return (0); 411280304Sjkim } 412280304Sjkim addr = start; 413238405Sjkim len = end - start; 414280304Sjkim } 415280304Sjkim#endif 416238405Sjkim 417280304Sjkim ap.addr = (void *) addr; 418280304Sjkim ap.len = len; 419280304Sjkim ap.prot = prot; 420280304Sjkim ap.flags = flags; 421280304Sjkim ap.fd = fd; 422280304Sjkim ap.pos = pos; 423280304Sjkim 424280304Sjkim return (mmap(td, &ap)); 425238405Sjkim} 426280304Sjkim 427238405Sjkimstruct itimerval32 { 428238405Sjkim struct timeval32 it_interval; 429280304Sjkim struct timeval32 it_value; 430280304Sjkim}; 431280304Sjkim 432280304SjkimCTASSERT(sizeof(struct itimerval32) == 16); 433280304Sjkim 434280304Sjkimint 435280304Sjkimfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 436280304Sjkim{ 437280304Sjkim int error; 438280304Sjkim caddr_t sg; 439280304Sjkim struct itimerval32 *p32, *op32, s32; 440280304Sjkim struct itimerval *p = NULL, *op = NULL, s; 441280304Sjkim 442280304Sjkim p32 = uap->itv; 443280304Sjkim if (p32) { 444280304Sjkim sg = stackgap_init(); 445280304Sjkim p = stackgap_alloc(&sg, sizeof(struct itimerval)); 446280304Sjkim uap->itv = (struct itimerval32 *)p; 447280304Sjkim error = copyin(p32, &s32, sizeof(s32)); 448280304Sjkim if (error) 449280304Sjkim return (error); 450280304Sjkim TV_CP(s32, s, it_interval); 451280304Sjkim TV_CP(s32, s, it_value); 452280304Sjkim error = copyout(&s, p, sizeof(s)); 453280304Sjkim if (error) 454280304Sjkim return (error); 455280304Sjkim } 456280304Sjkim op32 = uap->oitv; 457280304Sjkim if (op32) { 458280304Sjkim sg = stackgap_init(); 459280304Sjkim op = stackgap_alloc(&sg, sizeof(struct itimerval)); 460280304Sjkim uap->oitv = (struct itimerval32 *)op; 461280304Sjkim } 462238405Sjkim error = setitimer(td, (struct setitimer_args *) uap); 463238405Sjkim if (error) 464280304Sjkim return (error); 465280304Sjkim if (op32) { 466280304Sjkim error = copyin(op, &s, sizeof(s)); 467280304Sjkim if (error) 468280304Sjkim return (error); 469280304Sjkim TV_CP(s, s32, it_interval); 470238405Sjkim TV_CP(s, s32, it_value); 471280304Sjkim error = copyout(&s32, op32, sizeof(s32)); 472280304Sjkim } 473280304Sjkim return (error); 474280304Sjkim} 475280304Sjkim 476280304Sjkimint 477280304Sjkimfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 478280304Sjkim{ 479280304Sjkim int error; 480280304Sjkim caddr_t sg; 481280304Sjkim struct timeval32 *p32, s32; 482280304Sjkim struct timeval *p = NULL, s; 483280304Sjkim 484280304Sjkim p32 = uap->tv; 485280304Sjkim if (p32) { 486280304Sjkim sg = stackgap_init(); 487280304Sjkim p = stackgap_alloc(&sg, sizeof(struct timeval)); 488280304Sjkim uap->tv = (struct timeval32 *)p; 489280304Sjkim error = copyin(p32, &s32, sizeof(s32)); 490280304Sjkim if (error) 491238405Sjkim return (error); 492238405Sjkim CP(s32, s, tv_sec); 493280304Sjkim CP(s32, s, tv_usec); 494280304Sjkim error = copyout(&s, p, sizeof(s)); 495280304Sjkim if (error) 496280304Sjkim return (error); 497280304Sjkim } 498238405Sjkim /* 499238405Sjkim * XXX big-endian needs to convert the fd_sets too. 500280304Sjkim */ 501280304Sjkim return (select(td, (struct select_args *) uap)); 502280304Sjkim} 503238405Sjkim 504238405Sjkimstruct kevent32 { 505280304Sjkim u_int32_t ident; /* identifier for this event */ 506280304Sjkim short filter; /* filter for event */ 507280304Sjkim u_short flags; 508238405Sjkim u_int fflags; 50955714Skris int32_t data; 510280304Sjkim u_int32_t udata; /* opaque user data identifier */ 51155714Skris}; 512280304Sjkim 51355714SkrisCTASSERT(sizeof(struct kevent32) == 20); 514280304Sjkim 51555714Skrisint 516freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 517{ 518 int error; 519 caddr_t sg; 520 struct timespec32 ts32; 521 struct timespec ts; 522 struct kevent32 ks32; 523 struct kevent *ks; 524 struct kevent_args a; 525 int i; 526 527 sg = stackgap_init(); 528 529 a.fd = uap->fd; 530 a.changelist = uap->changelist; 531 a.nchanges = uap->nchanges; 532 a.eventlist = uap->eventlist; 533 a.nevents = uap->nevents; 534 a.timeout = NULL; 535 536 if (uap->timeout) { 537 a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 538 error = copyin(uap->timeout, &ts32, sizeof(ts32)); 539 if (error) 540 return (error); 541 CP(ts32, ts, tv_sec); 542 CP(ts32, ts, tv_nsec); 543 error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 544 if (error) 545 return (error); 546 } 547 if (uap->changelist) { 548 a.changelist = (struct kevent *)stackgap_alloc(&sg, 549 uap->nchanges * sizeof(struct kevent)); 550 for (i = 0; i < uap->nchanges; i++) { 551 error = copyin(&uap->changelist[i], &ks32, 552 sizeof(ks32)); 553 if (error) 554 return (error); 555 ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 556 CP(ks32, *ks, ident); 557 CP(ks32, *ks, filter); 558 CP(ks32, *ks, flags); 559 CP(ks32, *ks, fflags); 560 CP(ks32, *ks, data); 561 PTRIN_CP(ks32, *ks, udata); 562 } 563 } 564 if (uap->eventlist) { 565 a.eventlist = stackgap_alloc(&sg, 566 uap->nevents * sizeof(struct kevent)); 567 } 568 error = kevent(td, &a); 569 if (uap->eventlist && error > 0) { 570 for (i = 0; i < error; i++) { 571 ks = &a.eventlist[i]; 572 CP(*ks, ks32, ident); 573 CP(*ks, ks32, filter); 574 CP(*ks, ks32, flags); 575 CP(*ks, ks32, fflags); 576 CP(*ks, ks32, data); 577 PTROUT_CP(*ks, ks32, udata); 578 error = copyout(&ks32, &uap->eventlist[i], 579 sizeof(ks32)); 580 if (error) 581 return (error); 582 } 583 } 584 return error; 585} 586 587int 588freebsd32_gettimeofday(struct thread *td, 589 struct freebsd32_gettimeofday_args *uap) 590{ 591 struct timeval atv; 592 struct timeval32 atv32; 593 struct timezone rtz; 594 int error = 0; 595 596 if (uap->tp) { 597 microtime(&atv); 598 CP(atv, atv32, tv_sec); 599 CP(atv, atv32, tv_usec); 600 error = copyout(&atv32, uap->tp, sizeof (atv32)); 601 } 602 if (error == 0 && uap->tzp != NULL) { 603 rtz.tz_minuteswest = tz_minuteswest; 604 rtz.tz_dsttime = tz_dsttime; 605 error = copyout(&rtz, uap->tzp, sizeof (rtz)); 606 } 607 return (error); 608} 609 610int 611freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 612{ 613 int error; 614 caddr_t sg; 615 struct rusage32 *p32, s32; 616 struct rusage *p = NULL, s; 617 618 p32 = uap->rusage; 619 if (p32) { 620 sg = stackgap_init(); 621 p = stackgap_alloc(&sg, sizeof(struct rusage)); 622 uap->rusage = (struct rusage32 *)p; 623 } 624 error = getrusage(td, (struct getrusage_args *) uap); 625 if (error) 626 return (error); 627 if (p32) { 628 error = copyin(p, &s, sizeof(s)); 629 if (error) 630 return (error); 631 TV_CP(s, s32, ru_utime); 632 TV_CP(s, s32, ru_stime); 633 CP(s, s32, ru_maxrss); 634 CP(s, s32, ru_ixrss); 635 CP(s, s32, ru_idrss); 636 CP(s, s32, ru_isrss); 637 CP(s, s32, ru_minflt); 638 CP(s, s32, ru_majflt); 639 CP(s, s32, ru_nswap); 640 CP(s, s32, ru_inblock); 641 CP(s, s32, ru_oublock); 642 CP(s, s32, ru_msgsnd); 643 CP(s, s32, ru_msgrcv); 644 CP(s, s32, ru_nsignals); 645 CP(s, s32, ru_nvcsw); 646 CP(s, s32, ru_nivcsw); 647 error = copyout(&s32, p32, sizeof(s32)); 648 } 649 return (error); 650} 651 652struct iovec32 { 653 u_int32_t iov_base; 654 int iov_len; 655}; 656#define STACKGAPLEN 400 657 658CTASSERT(sizeof(struct iovec32) == 8); 659 660int 661freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 662{ 663 int error, osize, nsize, i; 664 caddr_t sg; 665 struct readv_args /* { 666 syscallarg(int) fd; 667 syscallarg(struct iovec *) iovp; 668 syscallarg(u_int) iovcnt; 669 } */ a; 670 struct iovec32 *oio; 671 struct iovec *nio; 672 673 sg = stackgap_init(); 674 675 if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 676 return (EINVAL); 677 678 osize = uap->iovcnt * sizeof (struct iovec32); 679 nsize = uap->iovcnt * sizeof (struct iovec); 680 681 oio = malloc(osize, M_TEMP, M_WAITOK); 682 nio = malloc(nsize, M_TEMP, M_WAITOK); 683 684 error = 0; 685 if ((error = copyin(uap->iovp, oio, osize))) 686 goto punt; 687 for (i = 0; i < uap->iovcnt; i++) { 688 nio[i].iov_base = PTRIN(oio[i].iov_base); 689 nio[i].iov_len = oio[i].iov_len; 690 } 691 692 a.fd = uap->fd; 693 a.iovp = stackgap_alloc(&sg, nsize); 694 a.iovcnt = uap->iovcnt; 695 696 if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 697 goto punt; 698 error = readv(td, &a); 699 700punt: 701 free(oio, M_TEMP); 702 free(nio, M_TEMP); 703 return (error); 704} 705 706int 707freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 708{ 709 int error, i, nsize, osize; 710 caddr_t sg; 711 struct writev_args /* { 712 syscallarg(int) fd; 713 syscallarg(struct iovec *) iovp; 714 syscallarg(u_int) iovcnt; 715 } */ a; 716 struct iovec32 *oio; 717 struct iovec *nio; 718 719 sg = stackgap_init(); 720 721 if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 722 return (EINVAL); 723 724 osize = uap->iovcnt * sizeof (struct iovec32); 725 nsize = uap->iovcnt * sizeof (struct iovec); 726 727 oio = malloc(osize, M_TEMP, M_WAITOK); 728 nio = malloc(nsize, M_TEMP, M_WAITOK); 729 730 error = 0; 731 if ((error = copyin(uap->iovp, oio, osize))) 732 goto punt; 733 for (i = 0; i < uap->iovcnt; i++) { 734 nio[i].iov_base = PTRIN(oio[i].iov_base); 735 nio[i].iov_len = oio[i].iov_len; 736 } 737 738 a.fd = uap->fd; 739 a.iovp = stackgap_alloc(&sg, nsize); 740 a.iovcnt = uap->iovcnt; 741 742 if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 743 goto punt; 744 error = writev(td, &a); 745 746punt: 747 free(oio, M_TEMP); 748 free(nio, M_TEMP); 749 return (error); 750} 751 752int 753freebsd32_settimeofday(struct thread *td, 754 struct freebsd32_settimeofday_args *uap) 755{ 756 int error; 757 caddr_t sg; 758 struct timeval32 *p32, s32; 759 struct timeval *p = NULL, s; 760 761 p32 = uap->tv; 762 if (p32) { 763 sg = stackgap_init(); 764 p = stackgap_alloc(&sg, sizeof(struct timeval)); 765 uap->tv = (struct timeval32 *)p; 766 error = copyin(p32, &s32, sizeof(s32)); 767 if (error) 768 return (error); 769 CP(s32, s, tv_sec); 770 CP(s32, s, tv_usec); 771 error = copyout(&s, p, sizeof(s)); 772 if (error) 773 return (error); 774 } 775 return (settimeofday(td, (struct settimeofday_args *) uap)); 776} 777 778int 779freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 780{ 781 int error; 782 caddr_t sg; 783 struct timeval32 *p32, s32[2]; 784 struct timeval *p = NULL, s[2]; 785 786 p32 = uap->tptr; 787 if (p32) { 788 sg = stackgap_init(); 789 p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 790 uap->tptr = (struct timeval32 *)p; 791 error = copyin(p32, s32, sizeof(s32)); 792 if (error) 793 return (error); 794 CP(s32[0], s[0], tv_sec); 795 CP(s32[0], s[0], tv_usec); 796 CP(s32[1], s[1], tv_sec); 797 CP(s32[1], s[1], tv_usec); 798 error = copyout(s, p, sizeof(s)); 799 if (error) 800 return (error); 801 } 802 return (utimes(td, (struct utimes_args *) uap)); 803} 804 805int 806freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 807{ 808 int error; 809 caddr_t sg; 810 struct timeval32 *p32, *op32, s32; 811 struct timeval *p = NULL, *op = NULL, s; 812 813 p32 = uap->delta; 814 if (p32) { 815 sg = stackgap_init(); 816 p = stackgap_alloc(&sg, sizeof(struct timeval)); 817 uap->delta = (struct timeval32 *)p; 818 error = copyin(p32, &s32, sizeof(s32)); 819 if (error) 820 return (error); 821 CP(s32, s, tv_sec); 822 CP(s32, s, tv_usec); 823 error = copyout(&s, p, sizeof(s)); 824 if (error) 825 return (error); 826 } 827 op32 = uap->olddelta; 828 if (op32) { 829 sg = stackgap_init(); 830 op = stackgap_alloc(&sg, sizeof(struct timeval)); 831 uap->olddelta = (struct timeval32 *)op; 832 } 833 error = utimes(td, (struct utimes_args *) uap); 834 if (error) 835 return error; 836 if (op32) { 837 error = copyin(op, &s, sizeof(s)); 838 if (error) 839 return (error); 840 CP(s, s32, tv_sec); 841 CP(s, s32, tv_usec); 842 error = copyout(&s32, op32, sizeof(s32)); 843 } 844 return (error); 845} 846 847int 848freebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap) 849{ 850 int error; 851 caddr_t sg; 852 struct statfs32 *p32, s32; 853 struct statfs *p = NULL, s; 854 855 p32 = uap->buf; 856 if (p32) { 857 sg = stackgap_init(); 858 p = stackgap_alloc(&sg, sizeof(struct statfs)); 859 uap->buf = (struct statfs32 *)p; 860 } 861 error = statfs(td, (struct statfs_args *) uap); 862 if (error) 863 return (error); 864 if (p32) { 865 error = copyin(p, &s, sizeof(s)); 866 if (error) 867 return (error); 868 copy_statfs(&s, &s32); 869 error = copyout(&s32, p32, sizeof(s32)); 870 } 871 return (error); 872} 873 874int 875freebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap) 876{ 877 int error; 878 caddr_t sg; 879 struct statfs32 *p32, s32; 880 struct statfs *p = NULL, s; 881 882 p32 = uap->buf; 883 if (p32) { 884 sg = stackgap_init(); 885 p = stackgap_alloc(&sg, sizeof(struct statfs)); 886 uap->buf = (struct statfs32 *)p; 887 } 888 error = fstatfs(td, (struct fstatfs_args *) uap); 889 if (error) 890 return (error); 891 if (p32) { 892 error = copyin(p, &s, sizeof(s)); 893 if (error) 894 return (error); 895 copy_statfs(&s, &s32); 896 error = copyout(&s32, p32, sizeof(s32)); 897 } 898 return (error); 899} 900 901int 902freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 903{ 904 /* 905 * Vector through to semsys if it is loaded. 906 */ 907 return sysent[169].sy_call(td, uap); 908} 909 910int 911freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 912{ 913 /* 914 * Vector through to msgsys if it is loaded. 915 */ 916 return sysent[170].sy_call(td, uap); 917} 918 919int 920freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 921{ 922 /* 923 * Vector through to shmsys if it is loaded. 924 */ 925 return sysent[171].sy_call(td, uap); 926} 927 928int 929freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 930{ 931 struct pread_args ap; 932 933 ap.fd = uap->fd; 934 ap.buf = uap->buf; 935 ap.nbyte = uap->nbyte; 936 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 937 return (pread(td, &ap)); 938} 939 940int 941freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 942{ 943 struct pwrite_args ap; 944 945 ap.fd = uap->fd; 946 ap.buf = uap->buf; 947 ap.nbyte = uap->nbyte; 948 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 949 return (pwrite(td, &ap)); 950} 951 952int 953freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 954{ 955 int error; 956 struct lseek_args ap; 957 off_t pos; 958 959 ap.fd = uap->fd; 960 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 961 ap.whence = uap->whence; 962 error = lseek(td, &ap); 963 /* Expand the quad return into two parts for eax and edx */ 964 pos = *(off_t *)(td->td_retval); 965 td->td_retval[0] = pos & 0xffffffff; /* %eax */ 966 td->td_retval[1] = pos >> 32; /* %edx */ 967 return error; 968} 969 970int 971freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 972{ 973 struct truncate_args ap; 974 975 ap.path = uap->path; 976 ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 977 return (truncate(td, &ap)); 978} 979 980int 981freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 982{ 983 struct ftruncate_args ap; 984 985 ap.fd = uap->fd; 986 ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 987 return (ftruncate(td, &ap)); 988} 989 990#ifdef COMPAT_FREEBSD4 991int 992freebsd4_freebsd32_sendfile(struct thread *td, 993 struct freebsd4_freebsd32_sendfile_args *uap) 994{ 995 struct freebsd4_sendfile_args ap; 996 997 ap.fd = uap->fd; 998 ap.s = uap->s; 999 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1000 ap.nbytes = uap->nbytes; /* XXX check */ 1001 ap.hdtr = uap->hdtr; /* XXX check */ 1002 ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1003 ap.flags = uap->flags; 1004 return (freebsd4_sendfile(td, &ap)); 1005} 1006#endif 1007 1008int 1009freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1010{ 1011 struct sendfile_args ap; 1012 1013 ap.fd = uap->fd; 1014 ap.s = uap->s; 1015 ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1016 ap.nbytes = uap->nbytes; /* XXX check */ 1017 ap.hdtr = uap->hdtr; /* XXX check */ 1018 ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1019 ap.flags = uap->flags; 1020 return (sendfile(td, &ap)); 1021} 1022 1023struct stat32 { 1024 udev_t st_dev; 1025 ino_t st_ino; 1026 mode_t st_mode; 1027 nlink_t st_nlink; 1028 uid_t st_uid; 1029 gid_t st_gid; 1030 udev_t st_rdev; 1031 struct timespec32 st_atimespec; 1032 struct timespec32 st_mtimespec; 1033 struct timespec32 st_ctimespec; 1034 off_t st_size; 1035 int64_t st_blocks; 1036 u_int32_t st_blksize; 1037 u_int32_t st_flags; 1038 u_int32_t st_gen; 1039 struct timespec32 st_birthtimespec; 1040 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1041 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1042}; 1043 1044 1045CTASSERT(sizeof(struct stat32) == 96); 1046 1047static void 1048copy_stat( struct stat *in, struct stat32 *out) 1049{ 1050 CP(*in, *out, st_dev); 1051 CP(*in, *out, st_ino); 1052 CP(*in, *out, st_mode); 1053 CP(*in, *out, st_nlink); 1054 CP(*in, *out, st_uid); 1055 CP(*in, *out, st_gid); 1056 CP(*in, *out, st_rdev); 1057 TS_CP(*in, *out, st_atimespec); 1058 TS_CP(*in, *out, st_mtimespec); 1059 TS_CP(*in, *out, st_ctimespec); 1060 CP(*in, *out, st_size); 1061 CP(*in, *out, st_blocks); 1062 CP(*in, *out, st_blksize); 1063 CP(*in, *out, st_flags); 1064 CP(*in, *out, st_gen); 1065} 1066 1067int 1068freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1069{ 1070 int error; 1071 caddr_t sg; 1072 struct stat32 *p32, s32; 1073 struct stat *p = NULL, s; 1074 1075 p32 = uap->ub; 1076 if (p32) { 1077 sg = stackgap_init(); 1078 p = stackgap_alloc(&sg, sizeof(struct stat)); 1079 uap->ub = (struct stat32 *)p; 1080 } 1081 error = stat(td, (struct stat_args *) uap); 1082 if (error) 1083 return (error); 1084 if (p32) { 1085 error = copyin(p, &s, sizeof(s)); 1086 if (error) 1087 return (error); 1088 copy_stat(&s, &s32); 1089 error = copyout(&s32, p32, sizeof(s32)); 1090 } 1091 return (error); 1092} 1093 1094int 1095freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1096{ 1097 int error; 1098 caddr_t sg; 1099 struct stat32 *p32, s32; 1100 struct stat *p = NULL, s; 1101 1102 p32 = uap->ub; 1103 if (p32) { 1104 sg = stackgap_init(); 1105 p = stackgap_alloc(&sg, sizeof(struct stat)); 1106 uap->ub = (struct stat32 *)p; 1107 } 1108 error = fstat(td, (struct fstat_args *) uap); 1109 if (error) 1110 return (error); 1111 if (p32) { 1112 error = copyin(p, &s, sizeof(s)); 1113 if (error) 1114 return (error); 1115 copy_stat(&s, &s32); 1116 error = copyout(&s32, p32, sizeof(s32)); 1117 } 1118 return (error); 1119} 1120 1121int 1122freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1123{ 1124 int error; 1125 caddr_t sg; 1126 struct stat32 *p32, s32; 1127 struct stat *p = NULL, s; 1128 1129 p32 = uap->ub; 1130 if (p32) { 1131 sg = stackgap_init(); 1132 p = stackgap_alloc(&sg, sizeof(struct stat)); 1133 uap->ub = (struct stat32 *)p; 1134 } 1135 error = lstat(td, (struct lstat_args *) uap); 1136 if (error) 1137 return (error); 1138 if (p32) { 1139 error = copyin(p, &s, sizeof(s)); 1140 if (error) 1141 return (error); 1142 copy_stat(&s, &s32); 1143 error = copyout(&s32, p32, sizeof(s32)); 1144 } 1145 return (error); 1146} 1147 1148/* 1149 * MPSAFE 1150 */ 1151int 1152freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1153{ 1154 int error, name[CTL_MAXNAME]; 1155 size_t j, oldlen; 1156 1157 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1158 return (EINVAL); 1159 1160 error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1161 if (error) 1162 return (error); 1163 1164 mtx_lock(&Giant); 1165 1166 if (uap->oldlenp) 1167 oldlen = fuword32(uap->oldlenp); 1168 else 1169 oldlen = 0; 1170 error = userland_sysctl(td, name, uap->namelen, 1171 uap->old, &oldlen, 1, 1172 uap->new, uap->newlen, &j); 1173 if (error && error != ENOMEM) 1174 goto done2; 1175 if (uap->oldlenp) { 1176 suword32(uap->oldlenp, j); 1177 } 1178done2: 1179 mtx_unlock(&Giant); 1180 return (error); 1181} 1182 1183struct sigaction32 { 1184 u_int32_t sa_u; 1185 int sa_flags; 1186 sigset_t sa_mask; 1187}; 1188 1189CTASSERT(sizeof(struct sigaction32) == 24); 1190 1191int 1192freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1193{ 1194 struct sigaction32 s32; 1195 struct sigaction sa, osa, *sap; 1196 int error; 1197 1198 if (uap->act) { 1199 error = copyin(uap->act, &s32, sizeof(s32)); 1200 if (error) 1201 return (error); 1202 sa.sa_handler = PTRIN(s32.sa_u); 1203 CP(s32, sa, sa_flags); 1204 CP(s32, sa, sa_mask); 1205 sap = &sa; 1206 } else 1207 sap = NULL; 1208 error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1209 if (error != 0 && uap->oact != NULL) { 1210 s32.sa_u = PTROUT(osa.sa_handler); 1211 CP(osa, s32, sa_flags); 1212 CP(osa, s32, sa_mask); 1213 error = copyout(&s32, uap->oact, sizeof(s32)); 1214 } 1215 return (error); 1216} 1217 1218#ifdef COMPAT_FREEBSD4 1219int 1220freebsd4_freebsd32_sigaction(struct thread *td, 1221 struct freebsd4_freebsd32_sigaction_args *uap) 1222{ 1223 struct sigaction32 s32; 1224 struct sigaction sa, osa, *sap; 1225 int error; 1226 1227 if (uap->act) { 1228 error = copyin(uap->act, &s32, sizeof(s32)); 1229 if (error) 1230 return (error); 1231 sa.sa_handler = PTRIN(s32.sa_u); 1232 CP(s32, sa, sa_flags); 1233 CP(s32, sa, sa_mask); 1234 sap = &sa; 1235 } else 1236 sap = NULL; 1237 error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1238 if (error != 0 && uap->oact != NULL) { 1239 s32.sa_u = PTROUT(osa.sa_handler); 1240 CP(osa, s32, sa_flags); 1241 CP(osa, s32, sa_mask); 1242 error = copyout(&s32, uap->oact, sizeof(s32)); 1243 } 1244 return (error); 1245} 1246#endif 1247 1248#if 0 1249 1250int 1251freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1252{ 1253 int error; 1254 caddr_t sg; 1255 struct yyy32 *p32, s32; 1256 struct yyy *p = NULL, s; 1257 1258 p32 = uap->zzz; 1259 if (p32) { 1260 sg = stackgap_init(); 1261 p = stackgap_alloc(&sg, sizeof(struct yyy)); 1262 uap->zzz = (struct yyy32 *)p; 1263 error = copyin(p32, &s32, sizeof(s32)); 1264 if (error) 1265 return (error); 1266 /* translate in */ 1267 error = copyout(&s, p, sizeof(s)); 1268 if (error) 1269 return (error); 1270 } 1271 error = xxx(td, (struct xxx_args *) uap); 1272 if (error) 1273 return (error); 1274 if (p32) { 1275 error = copyin(p, &s, sizeof(s)); 1276 if (error) 1277 return (error); 1278 /* translate out */ 1279 error = copyout(&s32, p32, sizeof(s32)); 1280 } 1281 return (error); 1282} 1283 1284#endif 1285