freebsd32_misc.c revision 172003
1139749Simp/*- 2139749Simp * Copyright (c) 2002 Doug Rabson 395584Sanholt * All rights reserved. 495584Sanholt * 5182080Srnoland * Redistribution and use in source and binary forms, with or without 695584Sanholt * modification, are permitted provided that the following conditions 795584Sanholt * are met: 895584Sanholt * 1. Redistributions of source code must retain the above copyright 995584Sanholt * notice, this list of conditions and the following disclaimer. 1095584Sanholt * 2. Redistributions in binary form must reproduce the above copyright 1195584Sanholt * notice, this list of conditions and the following disclaimer in the 1295584Sanholt * documentation and/or other materials provided with the distribution. 1395584Sanholt * 1495584Sanholt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1595584Sanholt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1695584Sanholt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1795584Sanholt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1895584Sanholt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1995584Sanholt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2095584Sanholt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2195584Sanholt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2295584Sanholt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2395584Sanholt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2495584Sanholt * SUCH DAMAGE. 2595584Sanholt */ 2695584Sanholt 2795584Sanholt#include <sys/cdefs.h> 2895584Sanholt__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 172003 2007-08-28 20:28:12Z jhb $"); 2995584Sanholt 3095584Sanholt#include "opt_compat.h" 3195584Sanholt 32152909Sanholt#include <sys/param.h> 33152909Sanholt#include <sys/systm.h> 34152909Sanholt#include <sys/bus.h> 3595584Sanholt#include <sys/clock.h> 36112015Sanholt#include <sys/exec.h> 3795746Sanholt#include <sys/fcntl.h> 3895584Sanholt#include <sys/filedesc.h> 39148211Sanholt#include <sys/namei.h> 4095584Sanholt#include <sys/imgact.h> 41182080Srnoland#include <sys/kernel.h> 4295584Sanholt#include <sys/limits.h> 4395584Sanholt#include <sys/lock.h> 44182080Srnoland#include <sys/malloc.h> 45182080Srnoland#include <sys/file.h> /* Must come after sys/malloc.h */ 4695584Sanholt#include <sys/mbuf.h> 47182080Srnoland#include <sys/mman.h> 48182080Srnoland#include <sys/module.h> 49182080Srnoland#include <sys/mount.h> 50182080Srnoland#include <sys/mutex.h> 51182080Srnoland#include <sys/proc.h> 52182080Srnoland#include <sys/reboot.h> 53182080Srnoland#include <sys/resource.h> 54182080Srnoland#include <sys/resourcevar.h> 55112015Sanholt#include <sys/selinfo.h> 56182080Srnoland#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ 57182080Srnoland#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 58182080Srnoland#include <sys/signal.h> 59182080Srnoland#include <sys/signalvar.h> 60182080Srnoland#include <sys/socket.h> 61182080Srnoland#include <sys/socketvar.h> 62182080Srnoland#include <sys/stat.h> 63182080Srnoland#include <sys/syscall.h> 64112015Sanholt#include <sys/syscallsubr.h> 65182080Srnoland#include <sys/sysctl.h> 66182080Srnoland#include <sys/sysent.h> 67182080Srnoland#include <sys/sysproto.h> 68182080Srnoland#include <sys/thr.h> 69182080Srnoland#include <sys/unistd.h> 70182080Srnoland#include <sys/ucontext.h> 71182080Srnoland#include <sys/vnode.h> 72182080Srnoland#include <sys/wait.h> 7395584Sanholt#include <sys/ipc.h> 74182080Srnoland#include <sys/shm.h> 7595584Sanholt 76183828Srnoland#include <vm/vm.h> 77183828Srnoland#include <vm/vm_kern.h> 78182080Srnoland#include <vm/vm_param.h> 79182080Srnoland#include <vm/pmap.h> 80182080Srnoland#include <vm/vm_map.h> 81182080Srnoland#include <vm/vm_object.h> 82182080Srnoland#include <vm/vm_extern.h> 83182080Srnoland 84182080Srnoland#include <machine/cpu.h> 85182080Srnoland 86182080Srnoland#include <compat/freebsd32/freebsd32_util.h> 87182080Srnoland#include <compat/freebsd32/freebsd32.h> 88183828Srnoland#include <compat/freebsd32/freebsd32_signal.h> 89183828Srnoland#include <compat/freebsd32/freebsd32_proto.h> 90182080Srnoland 91182080SrnolandCTASSERT(sizeof(struct timeval32) == 8); 92182080SrnolandCTASSERT(sizeof(struct timespec32) == 8); 93182080SrnolandCTASSERT(sizeof(struct statfs32) == 256); 94182080SrnolandCTASSERT(sizeof(struct rusage32) == 72); 95182080Srnoland 96182080Srnolandint 97182080Srnolandfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 98182080Srnoland{ 99182080Srnoland int error, status; 100182080Srnoland struct rusage32 ru32; 101183828Srnoland struct rusage ru, *rup; 102183828Srnoland 103182080Srnoland if (uap->rusage != NULL) 104182080Srnoland rup = &ru; 105182080Srnoland else 106182080Srnoland rup = NULL; 107182080Srnoland error = kern_wait(td, uap->pid, &status, uap->options, rup); 108182080Srnoland if (error) 109182080Srnoland return (error); 110182080Srnoland if (uap->status != NULL) 111182080Srnoland error = copyout(&status, uap->status, sizeof(status)); 112182080Srnoland if (uap->rusage != NULL && error == 0) { 113182080Srnoland TV_CP(ru, ru32, ru_utime); 114183828Srnoland TV_CP(ru, ru32, ru_stime); 115183828Srnoland CP(ru, ru32, ru_maxrss); 116182080Srnoland CP(ru, ru32, ru_ixrss); 117182080Srnoland CP(ru, ru32, ru_idrss); 118182080Srnoland CP(ru, ru32, ru_isrss); 119182080Srnoland CP(ru, ru32, ru_minflt); 120182080Srnoland CP(ru, ru32, ru_majflt); 121182080Srnoland CP(ru, ru32, ru_nswap); 122182080Srnoland CP(ru, ru32, ru_inblock); 123182080Srnoland CP(ru, ru32, ru_oublock); 124182080Srnoland CP(ru, ru32, ru_msgsnd); 125182080Srnoland CP(ru, ru32, ru_msgrcv); 126182080Srnoland CP(ru, ru32, ru_nsignals); 127182080Srnoland CP(ru, ru32, ru_nvcsw); 128182080Srnoland CP(ru, ru32, ru_nivcsw); 129182080Srnoland error = copyout(&ru32, uap->rusage, sizeof(ru32)); 130182080Srnoland } 131183828Srnoland return (error); 132183828Srnoland} 133182080Srnoland 134182080Srnoland#ifdef COMPAT_FREEBSD4 135182080Srnolandstatic void 136182080Srnolandcopy_statfs(struct statfs *in, struct statfs32 *out) 137182080Srnoland{ 138182080Srnoland 139182080Srnoland statfs_scale_blocks(in, INT32_MAX); 140182080Srnoland bzero(out, sizeof(*out)); 141182080Srnoland CP(*in, *out, f_bsize); 142182080Srnoland out->f_iosize = MIN(in->f_iosize, INT32_MAX); 143182080Srnoland CP(*in, *out, f_blocks); 144182080Srnoland CP(*in, *out, f_bfree); 145182080Srnoland CP(*in, *out, f_bavail); 146182080Srnoland out->f_files = MIN(in->f_files, INT32_MAX); 147182080Srnoland out->f_ffree = MIN(in->f_ffree, INT32_MAX); 148182080Srnoland CP(*in, *out, f_fsid); 149182080Srnoland CP(*in, *out, f_owner); 150182080Srnoland CP(*in, *out, f_type); 15195584Sanholt CP(*in, *out, f_flags); 15295584Sanholt out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX); 15395584Sanholt out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX); 15495584Sanholt strlcpy(out->f_fstypename, 15595584Sanholt in->f_fstypename, MFSNAMELEN); 15695584Sanholt strlcpy(out->f_mntonname, 157182080Srnoland in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 158148211Sanholt out->f_syncreads = MIN(in->f_syncreads, INT32_MAX); 159148211Sanholt out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX); 160148211Sanholt strlcpy(out->f_mntfromname, 161148211Sanholt in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 162148211Sanholt} 16395584Sanholt#endif 164145132Sanholt 16595584Sanholt#ifdef COMPAT_FREEBSD4 166145132Sanholtint 167145132Sanholtfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 168145132Sanholt{ 169145132Sanholt struct statfs *buf, *sp; 170145132Sanholt struct statfs32 stat32; 171145132Sanholt size_t count, size; 172145132Sanholt int error; 173145132Sanholt 174145132Sanholt count = uap->bufsize / sizeof(struct statfs32); 175145132Sanholt size = count * sizeof(struct statfs); 176145132Sanholt error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 177145132Sanholt if (size > 0) { 178145132Sanholt count = td->td_retval[0]; 179145132Sanholt sp = buf; 180145132Sanholt while (count > 0 && error == 0) { 181145132Sanholt copy_statfs(sp, &stat32); 182145132Sanholt error = copyout(&stat32, uap->buf, sizeof(stat32)); 18395584Sanholt sp++; 18495584Sanholt uap->buf++; 18595584Sanholt count--; 18695584Sanholt } 18795584Sanholt free(buf, M_TEMP); 18895584Sanholt } 18995584Sanholt return (error); 190145132Sanholt} 19195584Sanholt#endif 19295584Sanholt 19395584SanholtCTASSERT(sizeof(struct sigaltstack32) == 12); 19495584Sanholt 195112015Sanholtint 196112015Sanholtfreebsd32_sigaltstack(struct thread *td, 197182080Srnoland struct freebsd32_sigaltstack_args *uap) 198182080Srnoland{ 199182080Srnoland struct sigaltstack32 s32; 200182080Srnoland struct sigaltstack ss, oss, *ssp; 20195584Sanholt int error; 202182080Srnoland 203182080Srnoland if (uap->ss != NULL) { 204182080Srnoland error = copyin(uap->ss, &s32, sizeof(s32)); 205182080Srnoland if (error) 206182080Srnoland return (error); 207182080Srnoland PTRIN_CP(s32, ss, ss_sp); 20895584Sanholt CP(s32, ss, ss_size); 209182080Srnoland CP(s32, ss, ss_flags); 210182080Srnoland ssp = &ss; 211182080Srnoland } else 21295584Sanholt ssp = NULL; 21395584Sanholt error = kern_sigaltstack(td, ssp, &oss); 21495584Sanholt if (error == 0 && uap->oss != NULL) { 215145132Sanholt PTROUT_CP(oss, s32, ss_sp); 216145132Sanholt CP(oss, s32, ss_size); 21795584Sanholt CP(oss, s32, ss_flags); 218182080Srnoland error = copyout(&s32, uap->oss, sizeof(s32)); 21995584Sanholt } 22095584Sanholt return (error); 221145132Sanholt} 22295584Sanholt 22395584Sanholt/* 22495584Sanholt * Custom version of exec_copyin_args() so that we can translate 225112015Sanholt * the pointers. 226112015Sanholt */ 227145132Sanholtstatic int 228145132Sanholtfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 229145132Sanholt enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 230145132Sanholt{ 231145132Sanholt char *argp, *envp; 232145132Sanholt u_int32_t *p32, arg; 23395584Sanholt size_t length; 234182080Srnoland int error; 235182080Srnoland 236182080Srnoland bzero(args, sizeof(*args)); 23795584Sanholt if (argv == NULL) 23895584Sanholt return (EFAULT); 239145132Sanholt 240145132Sanholt /* 24195584Sanholt * Allocate temporary demand zeroed space for argument and 242182080Srnoland * environment strings 24395584Sanholt */ 24495584Sanholt args->buf = (char *) kmem_alloc_wait(exec_map, 245145132Sanholt PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 24695584Sanholt if (args->buf == NULL) 24795584Sanholt return (ENOMEM); 24895584Sanholt args->begin_argv = args->buf; 249112015Sanholt args->endp = args->begin_argv; 250112015Sanholt args->stringspace = ARG_MAX; 251145132Sanholt 252145132Sanholt args->fname = args->buf + ARG_MAX; 253145132Sanholt 254112015Sanholt /* 255145132Sanholt * Copy the file name. 256145132Sanholt */ 257145132Sanholt error = (segflg == UIO_SYSSPACE) ? 258145132Sanholt copystr(fname, args->fname, PATH_MAX, &length) : 25995584Sanholt copyinstr(fname, args->fname, PATH_MAX, &length); 26095584Sanholt if (error != 0) 261145132Sanholt goto err_exit; 26295584Sanholt 263182080Srnoland /* 264182080Srnoland * extract arguments first 265182080Srnoland */ 26695584Sanholt p32 = argv; 26795584Sanholt for (;;) { 268145132Sanholt error = copyin(p32++, &arg, sizeof(arg)); 269145132Sanholt if (error) 27095584Sanholt goto err_exit; 271182080Srnoland if (arg == 0) 27295584Sanholt break; 27395584Sanholt argp = PTRIN(arg); 274182080Srnoland error = copyinstr(argp, args->endp, args->stringspace, &length); 275182080Srnoland if (error) { 276182080Srnoland if (error == ENAMETOOLONG) 277182080Srnoland error = E2BIG; 278182080Srnoland goto err_exit; 279182080Srnoland } 280182080Srnoland args->stringspace -= length; 281182080Srnoland args->endp += length; 282182080Srnoland args->argc++; 283182080Srnoland } 284182080Srnoland 285182080Srnoland args->begin_envv = args->endp; 286182080Srnoland 287182080Srnoland /* 288182080Srnoland * extract environment strings 289182080Srnoland */ 290182080Srnoland if (envv) { 291182080Srnoland p32 = envv; 292182080Srnoland for (;;) { 293182080Srnoland error = copyin(p32++, &arg, sizeof(arg)); 294182080Srnoland if (error) 295182080Srnoland goto err_exit; 296182080Srnoland if (arg == 0) 297182080Srnoland break; 298182080Srnoland envp = PTRIN(arg); 299182080Srnoland error = copyinstr(envp, args->endp, args->stringspace, 300182080Srnoland &length); 301182080Srnoland if (error) { 302182080Srnoland if (error == ENAMETOOLONG) 303182080Srnoland error = E2BIG; 304182080Srnoland goto err_exit; 305182080Srnoland } 306182080Srnoland args->stringspace -= length; 307182080Srnoland args->endp += length; 308182080Srnoland args->envc++; 309182080Srnoland } 310182080Srnoland } 311182080Srnoland 312182080Srnoland return (0); 313182080Srnoland 314182080Srnolanderr_exit: 315182080Srnoland kmem_free_wakeup(exec_map, (vm_offset_t)args->buf, 316182080Srnoland PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 317182080Srnoland args->buf = NULL; 31895584Sanholt return (error); 31995584Sanholt} 32095584Sanholt 32195584Sanholtint 32295584Sanholtfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 323145132Sanholt{ 32495584Sanholt struct image_args eargs; 32595584Sanholt int error; 326145132Sanholt 32795584Sanholt error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 328145132Sanholt uap->argv, uap->envv); 32995584Sanholt if (error == 0) 330145132Sanholt error = kern_execve(td, &eargs, NULL); 331112015Sanholt return (error); 332182080Srnoland} 333182080Srnoland 334182080Srnoland#ifdef __ia64__ 335182080Srnolandstatic int 336182080Srnolandfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 337182080Srnoland int prot, int fd, off_t pos) 338182080Srnoland{ 339182080Srnoland vm_map_t map; 340182080Srnoland vm_map_entry_t entry; 341182080Srnoland int rv; 342182080Srnoland 343182080Srnoland map = &td->td_proc->p_vmspace->vm_map; 344182080Srnoland if (fd != -1) 345182080Srnoland prot |= VM_PROT_WRITE; 346182080Srnoland 347182080Srnoland if (vm_map_lookup_entry(map, start, &entry)) { 348112015Sanholt if ((entry->protection & prot) != prot) { 349145132Sanholt rv = vm_map_protect(map, 350145132Sanholt trunc_page(start), 351145132Sanholt round_page(end), 352145132Sanholt entry->protection | prot, 353145132Sanholt FALSE); 354112015Sanholt if (rv != KERN_SUCCESS) 355182080Srnoland return (EINVAL); 356182080Srnoland } 357182080Srnoland } else { 358182080Srnoland vm_offset_t addr = trunc_page(start); 359182080Srnoland rv = vm_map_find(map, 0, 0, 360182080Srnoland &addr, PAGE_SIZE, FALSE, prot, 361145132Sanholt VM_PROT_ALL, 0); 362157617Sanholt if (rv != KERN_SUCCESS) 363157617Sanholt return (EINVAL); 364157617Sanholt } 365157617Sanholt 366157617Sanholt if (fd != -1) { 367112015Sanholt struct pread_args r; 368182080Srnoland r.fd = fd; 369183830Srnoland r.buf = (void *) start; 370182080Srnoland r.nbyte = end - start; 371182080Srnoland r.offset = pos; 372145132Sanholt return (pread(td, &r)); 373145132Sanholt } else { 374182080Srnoland while (start < end) { 375145132Sanholt subyte((void *) start, 0); 376182080Srnoland start++; 377145132Sanholt } 378183828Srnoland return (0); 379183828Srnoland } 380183828Srnoland} 381182080Srnoland#endif 382182080Srnoland 383182080Srnolandint 384182080Srnolandfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 385182080Srnoland{ 386182080Srnoland struct mmap_args ap; 387182080Srnoland vm_offset_t addr = (vm_offset_t) uap->addr; 388182080Srnoland vm_size_t len = uap->len; 389182080Srnoland int prot = uap->prot; 390182080Srnoland int flags = uap->flags; 391182080Srnoland int fd = uap->fd; 392182080Srnoland off_t pos = (uap->poslo 393182080Srnoland | ((off_t)uap->poshi << 32)); 394182080Srnoland#ifdef __ia64__ 395182080Srnoland vm_size_t pageoff; 396182080Srnoland int error; 397182080Srnoland 398182080Srnoland /* 399182080Srnoland * Attempt to handle page size hassles. 400112015Sanholt */ 40195584Sanholt pageoff = (pos & PAGE_MASK); 40295584Sanholt if (flags & MAP_FIXED) { 40395584Sanholt vm_offset_t start, end; 40495584Sanholt start = addr; 40595584Sanholt end = addr + len; 40695584Sanholt 407145132Sanholt if (start != trunc_page(start)) { 40895584Sanholt error = freebsd32_mmap_partial(td, start, 409145132Sanholt round_page(start), prot, 41095584Sanholt fd, pos); 41195584Sanholt if (fd != -1) 41295584Sanholt pos += round_page(start) - start; 413145132Sanholt start = round_page(start); 414145132Sanholt } 41595584Sanholt if (end != round_page(end)) { 41695584Sanholt vm_offset_t t = trunc_page(end); 41795584Sanholt error = freebsd32_mmap_partial(td, t, end, 41895584Sanholt prot, fd, 41995584Sanholt pos + t - start); 420145132Sanholt end = trunc_page(end); 42195584Sanholt } 42295584Sanholt if (end > start && fd != -1 && (pos & PAGE_MASK)) { 423145132Sanholt /* 42495584Sanholt * We can't map this region at all. The specified 425145132Sanholt * address doesn't have the same alignment as the file 42695584Sanholt * position. Fake the mapping by simply reading the 42795584Sanholt * entire region into memory. First we need to make 42895584Sanholt * sure the region exists. 42995584Sanholt */ 43095584Sanholt vm_map_t map; 43195584Sanholt struct pread_args r; 432112015Sanholt int rv; 43395584Sanholt 434145132Sanholt prot |= VM_PROT_WRITE; 43595584Sanholt map = &td->td_proc->p_vmspace->vm_map; 43695584Sanholt rv = vm_map_remove(map, start, end); 43795584Sanholt if (rv != KERN_SUCCESS) 43895584Sanholt return (EINVAL); 439145132Sanholt rv = vm_map_find(map, 0, 0, 44095584Sanholt &start, end - start, FALSE, 44195584Sanholt prot, VM_PROT_ALL, 0); 442145132Sanholt if (rv != KERN_SUCCESS) 44395584Sanholt return (EINVAL); 444145132Sanholt r.fd = fd; 44595584Sanholt r.buf = (void *) start; 446145132Sanholt r.nbyte = end - start; 44795584Sanholt r.offset = pos; 44895584Sanholt error = pread(td, &r); 44995584Sanholt if (error) 450182080Srnoland return (error); 451182080Srnoland 452182080Srnoland td->td_retval[0] = addr; 453182080Srnoland return (0); 454182080Srnoland } 455182080Srnoland if (end == start) { 456182080Srnoland /* 45795584Sanholt * After dealing with the ragged ends, there 45895584Sanholt * might be none left. 45995584Sanholt */ 46095584Sanholt td->td_retval[0] = addr; 461112015Sanholt return (0); 462182080Srnoland } 463182080Srnoland addr = start; 46495584Sanholt len = end - start; 46595584Sanholt } 46695584Sanholt#endif 46795584Sanholt 46895584Sanholt ap.addr = (void *) addr; 46995584Sanholt ap.len = len; 470145132Sanholt ap.prot = prot; 47195584Sanholt ap.flags = flags; 47295584Sanholt ap.fd = fd; 473145132Sanholt ap.pos = pos; 47495584Sanholt 475145132Sanholt return (mmap(td, &ap)); 476145132Sanholt} 477145132Sanholt 47895584Sanholt#ifdef COMPAT_FREEBSD6 47995584Sanholtint 48095584Sanholtfreebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap) 48195584Sanholt{ 48295584Sanholt struct freebsd32_mmap_args ap; 48395584Sanholt 48495584Sanholt ap.addr = uap->addr; 485145132Sanholt ap.len = uap->len; 48695584Sanholt ap.prot = uap->prot; 487145132Sanholt ap.flags = uap->flags; 48895584Sanholt ap.fd = uap->fd; 489145132Sanholt ap.poslo = uap->poslo; 49095584Sanholt ap.poshi = uap->poshi; 49195584Sanholt 49295584Sanholt return (freebsd32_mmap(td, &ap)); 49395584Sanholt} 49495584Sanholt#endif 49595584Sanholt 496182080Srnolandstruct itimerval32 { 49795584Sanholt struct timeval32 it_interval; 49895584Sanholt struct timeval32 it_value; 499182080Srnoland}; 500145132Sanholt 50195584SanholtCTASSERT(sizeof(struct itimerval32) == 16); 502145132Sanholt 50395584Sanholtint 504182080Srnolandfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 505182080Srnoland{ 506182080Srnoland struct itimerval itv, oitv, *itvp; 507182080Srnoland struct itimerval32 i32; 50895584Sanholt int error; 509182080Srnoland 510182080Srnoland if (uap->itv != NULL) { 511182080Srnoland error = copyin(uap->itv, &i32, sizeof(i32)); 512182080Srnoland if (error) 513182080Srnoland return (error); 514182080Srnoland TV_CP(i32, itv, it_interval); 515182080Srnoland TV_CP(i32, itv, it_value); 516182080Srnoland itvp = &itv; 51795584Sanholt } else 518145132Sanholt itvp = NULL; 51995584Sanholt error = kern_setitimer(td, uap->which, itvp, &oitv); 520145132Sanholt if (error || uap->oitv == NULL) 521145132Sanholt return (error); 522145132Sanholt TV_CP(oitv, i32, it_interval); 523145132Sanholt TV_CP(oitv, i32, it_value); 524145132Sanholt return (copyout(&i32, uap->oitv, sizeof(i32))); 525145132Sanholt} 526145132Sanholt 527145132Sanholtint 528145132Sanholtfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 529145132Sanholt{ 530145132Sanholt struct itimerval itv; 53195584Sanholt struct itimerval32 i32; 53295584Sanholt int error; 53395584Sanholt 53495584Sanholt error = kern_getitimer(td, uap->which, &itv); 53595584Sanholt if (error || uap->itv == NULL) 536145132Sanholt return (error); 537145132Sanholt TV_CP(itv, i32, it_interval); 53895584Sanholt TV_CP(itv, i32, it_value); 539182080Srnoland return (copyout(&i32, uap->itv, sizeof(i32))); 540182080Srnoland} 541182080Srnoland 542182080Srnolandint 543182080Srnolandfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 54495584Sanholt{ 545182080Srnoland struct timeval32 tv32; 546182080Srnoland struct timeval tv, *tvp; 547182080Srnoland int error; 548182080Srnoland 54995584Sanholt if (uap->tv != NULL) { 550145132Sanholt error = copyin(uap->tv, &tv32, sizeof(tv32)); 55195584Sanholt if (error) 55295584Sanholt return (error); 55395584Sanholt CP(tv32, tv, tv_sec); 55495584Sanholt CP(tv32, tv, tv_usec); 55595584Sanholt tvp = &tv; 556145132Sanholt } else 55795584Sanholt tvp = NULL; 55895584Sanholt /* 55995584Sanholt * XXX big-endian needs to convert the fd_sets too. 56095584Sanholt * XXX Do pointers need PTRIN()? 561182080Srnoland */ 562145132Sanholt return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 56395584Sanholt} 56495584Sanholt 56595584Sanholtstruct kevent32 { 566182080Srnoland u_int32_t ident; /* identifier for this event */ 567157617Sanholt short filter; /* filter for event */ 568157617Sanholt u_short flags; 569157617Sanholt u_int fflags; 570157617Sanholt int32_t data; 571157617Sanholt u_int32_t udata; /* opaque user data identifier */ 572157617Sanholt}; 573182080Srnoland 574157617SanholtCTASSERT(sizeof(struct kevent32) == 20); 575157617Sanholtstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 57695584Sanholtstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 577145132Sanholt 578182080Srnoland/* 579182080Srnoland * Copy 'count' items into the destination list pointed to by uap->eventlist. 580182080Srnoland */ 581182080Srnolandstatic int 582145132Sanholtfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 583145132Sanholt{ 584145132Sanholt struct freebsd32_kevent_args *uap; 58595584Sanholt struct kevent32 ks32[KQ_NEVENTS]; 58695584Sanholt int i, error = 0; 587157617Sanholt 588157617Sanholt KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 589145132Sanholt uap = (struct freebsd32_kevent_args *)arg; 59095584Sanholt 59195584Sanholt for (i = 0; i < count; i++) { 592157617Sanholt CP(kevp[i], ks32[i], ident); 593157617Sanholt CP(kevp[i], ks32[i], filter); 59495584Sanholt CP(kevp[i], ks32[i], flags); 595145132Sanholt CP(kevp[i], ks32[i], fflags); 59695584Sanholt CP(kevp[i], ks32[i], data); 59795584Sanholt PTROUT_CP(kevp[i], ks32[i], udata); 598145132Sanholt } 59995584Sanholt error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 60095584Sanholt if (error == 0) 601145132Sanholt uap->eventlist += count; 602145132Sanholt return (error); 603145132Sanholt} 60495584Sanholt 60595584Sanholt/* 606145132Sanholt * Copy 'count' items from the list pointed to by uap->changelist. 607182080Srnoland */ 608145132Sanholtstatic int 609145132Sanholtfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 610145132Sanholt{ 611113995Sanholt struct freebsd32_kevent_args *uap; 612113995Sanholt struct kevent32 ks32[KQ_NEVENTS]; 613113995Sanholt int i, error = 0; 614182080Srnoland 61595584Sanholt KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 61695584Sanholt uap = (struct freebsd32_kevent_args *)arg; 617157617Sanholt 618157617Sanholt error = copyin(uap->changelist, ks32, count * sizeof *ks32); 61995584Sanholt if (error) 62095584Sanholt goto done; 621145132Sanholt uap->changelist += count; 622145132Sanholt 623145132Sanholt for (i = 0; i < count; i++) { 624145132Sanholt CP(ks32[i], kevp[i], ident); 62595584Sanholt CP(ks32[i], kevp[i], filter); 62695584Sanholt CP(ks32[i], kevp[i], flags); 627157617Sanholt CP(ks32[i], kevp[i], fflags); 628157617Sanholt CP(ks32[i], kevp[i], data); 629157617Sanholt PTRIN_CP(ks32[i], kevp[i], udata); 630182080Srnoland } 631182080Srnolanddone: 632182080Srnoland return (error); 633182080Srnoland} 634157617Sanholt 635182080Srnolandint 636182080Srnolandfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 637182080Srnoland{ 638182080Srnoland struct timespec32 ts32; 639157617Sanholt struct timespec ts, *tsp; 640157617Sanholt struct kevent_copyops k_ops = { uap, 641112015Sanholt freebsd32_kevent_copyout, 642112015Sanholt freebsd32_kevent_copyin}; 643112015Sanholt int error; 644112015Sanholt 645112015Sanholt 646112015Sanholt if (uap->timeout) { 647112015Sanholt error = copyin(uap->timeout, &ts32, sizeof(ts32)); 648145132Sanholt if (error) 649145132Sanholt return (error); 650112015Sanholt CP(ts32, ts, tv_sec); 651112015Sanholt CP(ts32, ts, tv_nsec); 652113995Sanholt tsp = &ts; 653112015Sanholt } else 654112015Sanholt tsp = NULL; 655145132Sanholt error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 656112015Sanholt &k_ops, tsp); 657157617Sanholt return (error); 658183830Srnoland} 659183830Srnoland 660183830Srnolandint 661183830Srnolandfreebsd32_gettimeofday(struct thread *td, 662183830Srnoland struct freebsd32_gettimeofday_args *uap) 663183830Srnoland{ 664183830Srnoland struct timeval atv; 665183830Srnoland struct timeval32 atv32; 666183830Srnoland struct timezone rtz; 667183830Srnoland int error = 0; 668183830Srnoland 669183830Srnoland if (uap->tp) { 670112015Sanholt microtime(&atv); 671112015Sanholt CP(atv, atv32, tv_sec); 672145132Sanholt CP(atv, atv32, tv_usec); 673112015Sanholt error = copyout(&atv32, uap->tp, sizeof (atv32)); 674112015Sanholt } 675145132Sanholt if (error == 0 && uap->tzp != NULL) { 676145132Sanholt rtz.tz_minuteswest = tz_minuteswest; 677112015Sanholt rtz.tz_dsttime = tz_dsttime; 678112015Sanholt error = copyout(&rtz, uap->tzp, sizeof (rtz)); 679145132Sanholt } 680112015Sanholt return (error); 681145132Sanholt} 68295584Sanholt 68395584Sanholtint 684145132Sanholtfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 685145132Sanholt{ 686145132Sanholt struct rusage32 s32; 687145132Sanholt struct rusage s; 688145132Sanholt int error; 689157617Sanholt 69095584Sanholt error = kern_getrusage(td, uap->who, &s); 69195584Sanholt if (error) 692157617Sanholt return (error); 693157617Sanholt if (uap->rusage != NULL) { 694157617Sanholt TV_CP(s, s32, ru_utime); 695157617Sanholt TV_CP(s, s32, ru_stime); 696157617Sanholt CP(s, s32, ru_maxrss); 697157617Sanholt CP(s, s32, ru_ixrss); 698157617Sanholt CP(s, s32, ru_idrss); 699157617Sanholt CP(s, s32, ru_isrss); 700157617Sanholt CP(s, s32, ru_minflt); 701157617Sanholt CP(s, s32, ru_majflt); 702157617Sanholt CP(s, s32, ru_nswap); 703157617Sanholt CP(s, s32, ru_inblock); 704157617Sanholt CP(s, s32, ru_oublock); 705157617Sanholt CP(s, s32, ru_msgsnd); 706157617Sanholt CP(s, s32, ru_msgrcv); 707157617Sanholt CP(s, s32, ru_nsignals); 708157617Sanholt CP(s, s32, ru_nvcsw); 709157617Sanholt CP(s, s32, ru_nivcsw); 710157617Sanholt error = copyout(&s32, uap->rusage, sizeof(s32)); 711157617Sanholt } 712157617Sanholt return (error); 713157617Sanholt} 714157617Sanholt 715157617Sanholtstruct iovec32 { 716157617Sanholt u_int32_t iov_base; 717157617Sanholt int iov_len; 718157617Sanholt}; 719157617Sanholt 720162132SanholtCTASSERT(sizeof(struct iovec32) == 8); 721162132Sanholt 722162132Sanholtstatic int 723162132Sanholtfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 724162132Sanholt{ 725162132Sanholt struct iovec32 iov32; 726157617Sanholt struct iovec *iov; 727157617Sanholt struct uio *uio; 728182080Srnoland u_int iovlen; 729182080Srnoland int error, i; 730182080Srnoland 731182080Srnoland *uiop = NULL; 732182080Srnoland if (iovcnt > UIO_MAXIOV) 733182080Srnoland return (EINVAL); 734182080Srnoland iovlen = iovcnt * sizeof(struct iovec); 735182080Srnoland uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 736182080Srnoland iov = (struct iovec *)(uio + 1); 737182080Srnoland for (i = 0; i < iovcnt; i++) { 738182080Srnoland error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 739182080Srnoland if (error) { 740182080Srnoland free(uio, M_IOV); 741183828Srnoland return (error); 742183828Srnoland } 743182080Srnoland iov[i].iov_base = PTRIN(iov32.iov_base); 744182080Srnoland iov[i].iov_len = iov32.iov_len; 745182080Srnoland } 746182080Srnoland uio->uio_iov = iov; 747182080Srnoland uio->uio_iovcnt = iovcnt; 748182080Srnoland uio->uio_segflg = UIO_USERSPACE; 749182080Srnoland uio->uio_offset = -1; 750182080Srnoland uio->uio_resid = 0; 751182080Srnoland for (i = 0; i < iovcnt; i++) { 752182080Srnoland if (iov->iov_len > INT_MAX - uio->uio_resid) { 753182080Srnoland free(uio, M_IOV); 754182080Srnoland return (EINVAL); 755182080Srnoland } 756182080Srnoland uio->uio_resid += iov->iov_len; 757182080Srnoland iov++; 758182080Srnoland } 759182080Srnoland *uiop = uio; 760182080Srnoland return (0); 761182080Srnoland} 762182080Srnoland 763182080Srnolandint 764182080Srnolandfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 765182080Srnoland{ 766182080Srnoland struct uio *auio; 767182080Srnoland int error; 768182080Srnoland 769182080Srnoland error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 770182080Srnoland if (error) 771182080Srnoland return (error); 772182080Srnoland error = kern_readv(td, uap->fd, auio); 773182080Srnoland free(auio, M_IOV); 774182080Srnoland return (error); 775182080Srnoland} 776182080Srnoland 777182080Srnolandint 778182080Srnolandfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 779182080Srnoland{ 780182080Srnoland struct uio *auio; 781182080Srnoland int error; 782182080Srnoland 783182080Srnoland error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 784182080Srnoland if (error) 785182080Srnoland return (error); 786182080Srnoland error = kern_writev(td, uap->fd, auio); 787182080Srnoland free(auio, M_IOV); 788182080Srnoland return (error); 789182080Srnoland} 790182080Srnoland 791182080Srnolandint 792182080Srnolandfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 793182080Srnoland{ 794182080Srnoland struct uio *auio; 795182080Srnoland int error; 796182080Srnoland 797182080Srnoland error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 798182080Srnoland if (error) 799182080Srnoland return (error); 800148211Sanholt error = kern_preadv(td, uap->fd, auio, uap->offset); 801148211Sanholt free(auio, M_IOV); 802148211Sanholt return (error); 803148211Sanholt} 804148211Sanholt 805152909Sanholtint 806157617Sanholtfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 807157617Sanholt{ 808152909Sanholt struct uio *auio; 809157617Sanholt int error; 810157617Sanholt 811157617Sanholt error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 812157617Sanholt if (error) 813157617Sanholt return (error); 814157617Sanholt error = kern_pwritev(td, uap->fd, auio, uap->offset); 815157617Sanholt free(auio, M_IOV); 816157617Sanholt return (error); 817157617Sanholt} 818148211Sanholt 819182080Srnolandstatic int 820148211Sanholtfreebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp, 821157617Sanholt int error) 822157617Sanholt{ 823148211Sanholt struct iovec32 iov32; 824157617Sanholt struct iovec *iov; 825157617Sanholt u_int iovlen; 826148211Sanholt int i; 827148211Sanholt 828148211Sanholt *iovp = NULL; 829119098Sanholt if (iovcnt > UIO_MAXIOV) 830145132Sanholt return (error); 831119098Sanholt iovlen = iovcnt * sizeof(struct iovec); 832152909Sanholt iov = malloc(iovlen, M_IOV, M_WAITOK); 833119098Sanholt for (i = 0; i < iovcnt; i++) { 834182080Srnoland error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32)); 835183828Srnoland if (error) { 836182080Srnoland free(iov, M_IOV); 837182080Srnoland return (error); 838182080Srnoland } 839182080Srnoland iov[i].iov_base = PTRIN(iov32.iov_base); 840182080Srnoland iov[i].iov_len = iov32.iov_len; 841182080Srnoland } 842148211Sanholt *iovp = iov; 843148211Sanholt return (0); 844148211Sanholt} 845148211Sanholt 846182080Srnolandstruct msghdr32 { 847152909Sanholt u_int32_t msg_name; 848145132Sanholt socklen_t msg_namelen; 849145132Sanholt u_int32_t msg_iov; 850145132Sanholt int msg_iovlen; 851119098Sanholt u_int32_t msg_control; 852119098Sanholt socklen_t msg_controllen; 853119098Sanholt int msg_flags; 854152909Sanholt}; 855119098SanholtCTASSERT(sizeof(struct msghdr32) == 28); 856119098Sanholt 857119098Sanholtstatic int 858145132Sanholtfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) 859145132Sanholt{ 860145132Sanholt struct msghdr32 m32; 861119098Sanholt int error; 862119895Sanholt 863119098Sanholt error = copyin(msg32, &m32, sizeof(m32)); 864182080Srnoland if (error) 865145132Sanholt return (error); 866119098Sanholt msg->msg_name = PTRIN(m32.msg_name); 867145132Sanholt msg->msg_namelen = m32.msg_namelen; 868145132Sanholt msg->msg_iov = PTRIN(m32.msg_iov); 869119098Sanholt msg->msg_iovlen = m32.msg_iovlen; 870119098Sanholt msg->msg_control = PTRIN(m32.msg_control); 871119098Sanholt msg->msg_controllen = m32.msg_controllen; 872182080Srnoland msg->msg_flags = m32.msg_flags; 87395584Sanholt return (0); 874145132Sanholt} 875157617Sanholt 876145132Sanholtstatic int 87795584Sanholtfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) 878157617Sanholt{ 879182080Srnoland struct msghdr32 m32; 880157617Sanholt int error; 881157617Sanholt 882182080Srnoland m32.msg_name = PTROUT(msg->msg_name); 883157617Sanholt m32.msg_namelen = msg->msg_namelen; 884157617Sanholt m32.msg_iov = PTROUT(msg->msg_iov); 885182080Srnoland m32.msg_iovlen = msg->msg_iovlen; 886152909Sanholt m32.msg_control = PTROUT(msg->msg_control); 887152909Sanholt m32.msg_controllen = msg->msg_controllen; 888182080Srnoland m32.msg_flags = msg->msg_flags; 889152909Sanholt error = copyout(&m32, msg32, sizeof(m32)); 890182080Srnoland return (error); 891162132Sanholt} 892162132Sanholt 893162132Sanholt#define FREEBSD32_ALIGNBYTES (sizeof(int) - 1) 894182080Srnoland#define FREEBSD32_ALIGN(p) \ 895162132Sanholt (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES) 896152909Sanholt#define FREEBSD32_CMSG_SPACE(l) \ 897182080Srnoland (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l)) 898145132Sanholt 89995584Sanholt#define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ 900182080Srnoland FREEBSD32_ALIGN(sizeof(struct cmsghdr))) 90195584Sanholtstatic int 90295584Sanholtfreebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control) 90395584Sanholt{ 904145132Sanholt struct cmsghdr *cm; 905145132Sanholt void *data; 906145132Sanholt socklen_t clen, datalen; 90795584Sanholt int error; 908182080Srnoland caddr_t ctlbuf; 90995584Sanholt int len, maxlen, copylen; 91095584Sanholt struct mbuf *m; 911182080Srnoland error = 0; 912182080Srnoland 913182080Srnoland len = msg->msg_controllen; 914145132Sanholt maxlen = msg->msg_controllen; 915112015Sanholt msg->msg_controllen = 0; 91695584Sanholt 91795584Sanholt m = control; 91895584Sanholt ctlbuf = msg->msg_control; 91995584Sanholt 92095584Sanholt while (m && len > 0) { 92195584Sanholt cm = mtod(m, struct cmsghdr *); 922145132Sanholt clen = m->m_len; 923145132Sanholt 924145132Sanholt while (cm != NULL) { 92595584Sanholt 926182080Srnoland if (sizeof(struct cmsghdr) > clen || 92795584Sanholt cm->cmsg_len > clen) { 92895584Sanholt error = EINVAL; 929145132Sanholt break; 93095584Sanholt } 93195584Sanholt 93295584Sanholt data = CMSG_DATA(cm); 93395584Sanholt datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 93495584Sanholt 93595584Sanholt /* Adjust message length */ 93695584Sanholt cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + 93795584Sanholt datalen; 938145132Sanholt 939145132Sanholt 940145132Sanholt /* Copy cmsghdr */ 941145132Sanholt copylen = sizeof(struct cmsghdr); 94295584Sanholt if (len < copylen) { 943145132Sanholt msg->msg_flags |= MSG_CTRUNC; 94495584Sanholt copylen = len; 94595584Sanholt } 94695584Sanholt 94795584Sanholt error = copyout(cm,ctlbuf,copylen); 94895584Sanholt if (error) 94995584Sanholt goto exit; 95095584Sanholt 95195584Sanholt ctlbuf += FREEBSD32_ALIGN(copylen); 952145132Sanholt len -= FREEBSD32_ALIGN(copylen); 953145132Sanholt 95495584Sanholt if (len <= 0) 95595584Sanholt break; 95695584Sanholt 95795584Sanholt /* Copy data */ 95895584Sanholt copylen = datalen; 95995584Sanholt if (len < copylen) { 96095584Sanholt msg->msg_flags |= MSG_CTRUNC; 96195584Sanholt copylen = len; 962182080Srnoland } 96395584Sanholt 964145132Sanholt error = copyout(data,ctlbuf,copylen); 965145132Sanholt if (error) 966145132Sanholt goto exit; 967145132Sanholt 968145132Sanholt ctlbuf += FREEBSD32_ALIGN(copylen); 969145132Sanholt len -= FREEBSD32_ALIGN(copylen); 970145132Sanholt 97195584Sanholt if (CMSG_SPACE(datalen) < clen) { 97295584Sanholt clen -= CMSG_SPACE(datalen); 97395584Sanholt cm = (struct cmsghdr *) 97495584Sanholt ((caddr_t)cm + CMSG_SPACE(datalen)); 97595584Sanholt } else { 97695584Sanholt clen = 0; 97795584Sanholt cm = NULL; 97895584Sanholt } 97995584Sanholt } 98095584Sanholt m = m->m_next; 98195584Sanholt } 98295584Sanholt 98395584Sanholt msg->msg_controllen = (len <= 0) ? maxlen : ctlbuf - (caddr_t)msg->msg_control; 984113995Sanholt 985113995Sanholtexit: 986113995Sanholt return (error); 987113995Sanholt 988119895Sanholt} 989145132Sanholt 990182080Srnolandint 991145132Sanholtfreebsd32_recvmsg(td, uap) 99295584Sanholt struct thread *td; 99395584Sanholt struct freebsd32_recvmsg_args /* { 994182080Srnoland int s; 99595584Sanholt struct msghdr32 *msg; 99695584Sanholt int flags; 997145132Sanholt } */ *uap; 998145132Sanholt{ 99995584Sanholt struct msghdr msg; 100095584Sanholt struct msghdr32 m32; 1001182080Srnoland struct iovec *uiov, *iov; 100295584Sanholt struct mbuf *control = NULL; 1003145132Sanholt struct mbuf **controlp; 1004145132Sanholt 100595584Sanholt int error; 100695584Sanholt error = copyin(uap->msg, &m32, sizeof(m32)); 1007182080Srnoland if (error) 100895584Sanholt return (error); 1009152909Sanholt error = freebsd32_copyinmsghdr(uap->msg, &msg); 1010145132Sanholt if (error) 1011145132Sanholt return (error); 101295584Sanholt error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 101395584Sanholt EMSGSIZE); 1014182080Srnoland if (error) 101595584Sanholt return (error); 101695584Sanholt msg.msg_flags = uap->flags; 1017145132Sanholt uiov = msg.msg_iov; 1018145132Sanholt msg.msg_iov = iov; 1019145132Sanholt 1020145132Sanholt controlp = (msg.msg_control != NULL) ? &control : NULL; 1021119895Sanholt error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp); 102295584Sanholt if (error == 0) { 1023182080Srnoland msg.msg_iov = uiov; 102495584Sanholt 102595584Sanholt if (control != NULL) 102695584Sanholt error = freebsd32_copy_msg_out(&msg, control); 102795584Sanholt 1028145132Sanholt if (error == 0) 1029145132Sanholt error = freebsd32_copyoutmsghdr(&msg, uap->msg); 103095584Sanholt } 1031145132Sanholt free(iov, M_IOV); 1032182080Srnoland 1033145132Sanholt if (control != NULL) 1034145132Sanholt m_freem(control); 1035145132Sanholt 1036145132Sanholt return (error); 1037145132Sanholt} 1038145132Sanholt 103995584Sanholt 104095584Sanholtstatic int 1041182080Srnolandfreebsd32_convert_msg_in(struct mbuf **controlp) 104295584Sanholt{ 1043119098Sanholt struct mbuf *control = *controlp; 1044119098Sanholt struct cmsghdr *cm = mtod(control, struct cmsghdr *); 1045119098Sanholt void *data; 1046145132Sanholt socklen_t clen = control->m_len, datalen; 104795584Sanholt int error; 1048145132Sanholt 1049145132Sanholt error = 0; 1050145132Sanholt *controlp = NULL; 105195584Sanholt 1052145132Sanholt while (cm != NULL) { 1053145132Sanholt if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) { 1054145132Sanholt error = EINVAL; 1055145132Sanholt break; 1056145132Sanholt } 1057145132Sanholt 105895584Sanholt data = FREEBSD32_CMSG_DATA(cm); 105995584Sanholt datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1060182080Srnoland 1061182080Srnoland *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type, 1062182080Srnoland cm->cmsg_level); 1063157617Sanholt controlp = &(*controlp)->m_next; 106495584Sanholt 1065145132Sanholt if (FREEBSD32_CMSG_SPACE(datalen) < clen) { 1066145132Sanholt clen -= FREEBSD32_CMSG_SPACE(datalen); 1067145132Sanholt cm = (struct cmsghdr *) 1068122580Sanholt ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen)); 1069145132Sanholt } else { 1070145132Sanholt clen = 0; 1071145132Sanholt cm = NULL; 1072122580Sanholt } 1073145132Sanholt } 1074145132Sanholt 1075145132Sanholt m_freem(control); 1076122580Sanholt return (error); 1077119895Sanholt} 1078122580Sanholt 1079157617Sanholt 1080157617Sanholtint 1081157617Sanholtfreebsd32_sendmsg(struct thread *td, 1082157617Sanholt struct freebsd32_sendmsg_args *uap) 1083157617Sanholt{ 1084157617Sanholt struct msghdr msg; 1085157617Sanholt struct msghdr32 m32; 1086157617Sanholt struct iovec *iov; 1087157617Sanholt struct mbuf *control = NULL; 1088157617Sanholt struct sockaddr *to = NULL; 1089145132Sanholt int error; 1090182080Srnoland 1091157617Sanholt error = copyin(uap->msg, &m32, sizeof(m32)); 1092157617Sanholt if (error) 1093182080Srnoland return (error); 1094182080Srnoland error = freebsd32_copyinmsghdr(uap->msg, &msg); 1095157617Sanholt if (error) 1096157617Sanholt return (error); 1097157617Sanholt error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 1098157617Sanholt EMSGSIZE); 1099157617Sanholt if (error) 1100157617Sanholt return (error); 1101157617Sanholt msg.msg_iov = iov; 1102157617Sanholt if (msg.msg_name != NULL) { 1103157617Sanholt error = getsockaddr(&to, msg.msg_name, msg.msg_namelen); 1104182080Srnoland if (error) { 1105182080Srnoland to = NULL; 1106157617Sanholt goto out; 1107157617Sanholt } 1108182080Srnoland msg.msg_name = to; 1109157617Sanholt } 1110157617Sanholt 1111157617Sanholt if (msg.msg_control) { 1112157617Sanholt if (msg.msg_controllen < sizeof(struct cmsghdr)) { 1113157617Sanholt error = EINVAL; 1114157617Sanholt goto out; 1115157617Sanholt } 1116157617Sanholt 1117157617Sanholt error = sockargs(&control, msg.msg_control, 1118157617Sanholt msg.msg_controllen, MT_CONTROL); 1119157617Sanholt if (error) 1120182080Srnoland goto out; 1121145132Sanholt 1122145132Sanholt error = freebsd32_convert_msg_in(&control); 1123145132Sanholt if (error) 112495584Sanholt goto out; 112595584Sanholt } 1126145132Sanholt 1127157617Sanholt error = kern_sendit(td, uap->s, &msg, uap->flags, control, 1128157617Sanholt UIO_USERSPACE); 112995584Sanholt 1130145132Sanholtout: 1131145132Sanholt free(iov, M_IOV); 1132145132Sanholt if (to) 1133145132Sanholt free(to, M_SONAME); 113495584Sanholt return (error); 1135145132Sanholt} 1136145132Sanholt 113795584Sanholtint 113895584Sanholtfreebsd32_recvfrom(struct thread *td, 1139145132Sanholt struct freebsd32_recvfrom_args *uap) 114095584Sanholt{ 1141182080Srnoland struct msghdr msg; 1142182080Srnoland struct iovec aiov; 1143182080Srnoland int error; 1144182080Srnoland 1145182080Srnoland if (uap->fromlenaddr) { 1146182080Srnoland error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen, 1147145132Sanholt sizeof(msg.msg_namelen)); 114895584Sanholt if (error) 114995584Sanholt return (error); 115095584Sanholt } else { 1151145132Sanholt msg.msg_namelen = 0; 1152182080Srnoland } 1153119098Sanholt 1154145132Sanholt msg.msg_name = PTRIN(uap->from); 1155119098Sanholt msg.msg_iov = &aiov; 1156119098Sanholt msg.msg_iovlen = 1; 1157119098Sanholt aiov.iov_base = PTRIN(uap->buf); 1158182080Srnoland aiov.iov_len = uap->len; 1159152909Sanholt msg.msg_control = NULL; 1160182080Srnoland msg.msg_flags = uap->flags; 1161157617Sanholt error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL); 1162157617Sanholt if (error == 0 && uap->fromlenaddr) 1163157617Sanholt error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr), 1164182080Srnoland sizeof (msg.msg_namelen)); 1165157617Sanholt return (error); 1166182080Srnoland} 1167157617Sanholt 1168182080Srnolandint 1169157617Sanholtfreebsd32_settimeofday(struct thread *td, 1170157617Sanholt struct freebsd32_settimeofday_args *uap) 1171152909Sanholt{ 1172182080Srnoland struct timeval32 tv32; 1173182080Srnoland struct timeval tv, *tvp; 1174182080Srnoland struct timezone tz, *tzp; 1175182080Srnoland int error; 1176157617Sanholt 1177157617Sanholt if (uap->tv) { 1178157617Sanholt error = copyin(uap->tv, &tv32, sizeof(tv32)); 1179157617Sanholt if (error) 1180157617Sanholt return (error); 1181157617Sanholt CP(tv32, tv, tv_sec); 1182157617Sanholt CP(tv32, tv, tv_usec); 1183182080Srnoland tvp = &tv; 1184182080Srnoland } else 1185182080Srnoland tvp = NULL; 1186182080Srnoland if (uap->tzp) { 1187157617Sanholt error = copyin(uap->tzp, &tz, sizeof(tz)); 1188157617Sanholt if (error) 1189152909Sanholt return (error); 1190152909Sanholt tzp = &tz; 1191182080Srnoland } else 1192157617Sanholt tzp = NULL; 1193157617Sanholt return (kern_settimeofday(td, tvp, tzp)); 1194152909Sanholt} 1195182080Srnoland 1196152909Sanholtint 1197152909Sanholtfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 1198152909Sanholt{ 1199152909Sanholt struct timeval32 s32[2]; 1200145132Sanholt struct timeval s[2], *sp; 120195584Sanholt int error; 1202182080Srnoland 120395584Sanholt if (uap->tptr != NULL) { 120495584Sanholt error = copyin(uap->tptr, s32, sizeof(s32)); 1205119098Sanholt if (error) 1206145132Sanholt return (error); 120795584Sanholt CP(s32[0], s[0], tv_sec); 120895584Sanholt CP(s32[0], s[0], tv_usec); 1209183573Srnoland CP(s32[1], s[1], tv_sec); 1210183573Srnoland CP(s32[1], s[1], tv_usec); 1211183573Srnoland sp = s; 1212145132Sanholt } else 1213145132Sanholt sp = NULL; 121495584Sanholt return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 121595584Sanholt} 121695584Sanholt 1217145132Sanholtint 1218157617Sanholtfreebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap) 121995584Sanholt{ 122095584Sanholt struct timeval32 s32[2]; 122195584Sanholt struct timeval s[2], *sp; 122295584Sanholt int error; 1223182080Srnoland 122495584Sanholt if (uap->tptr != NULL) { 1225145132Sanholt error = copyin(uap->tptr, s32, sizeof(s32)); 1226145132Sanholt if (error) 122795584Sanholt return (error); 1228119098Sanholt CP(s32[0], s[0], tv_sec); 1229119098Sanholt CP(s32[0], s[0], tv_usec); 1230119098Sanholt CP(s32[1], s[1], tv_sec); 1231119098Sanholt CP(s32[1], s[1], tv_usec); 1232145132Sanholt sp = s; 1233145132Sanholt } else 1234119098Sanholt sp = NULL; 1235145132Sanholt return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1236182080Srnoland} 1237145132Sanholt 1238145132Sanholtint 1239145132Sanholtfreebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap) 1240145132Sanholt{ 1241145132Sanholt struct timeval32 s32[2]; 1242145132Sanholt struct timeval s[2], *sp; 1243145132Sanholt int error; 1244145132Sanholt 1245145132Sanholt if (uap->tptr != NULL) { 1246145132Sanholt error = copyin(uap->tptr, s32, sizeof(s32)); 1247145132Sanholt if (error) 1248145132Sanholt return (error); 1249145132Sanholt CP(s32[0], s[0], tv_sec); 1250119098Sanholt CP(s32[0], s[0], tv_usec); 1251145132Sanholt CP(s32[1], s[1], tv_sec); 1252152909Sanholt CP(s32[1], s[1], tv_usec); 1253152909Sanholt sp = s; 1254152909Sanholt } else 1255152909Sanholt sp = NULL; 1256152909Sanholt return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE)); 1257152909Sanholt} 1258152909Sanholt 1259152909Sanholt 1260152909Sanholtint 1261152909Sanholtfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 1262152909Sanholt{ 1263152909Sanholt struct timeval32 tv32; 1264152909Sanholt struct timeval delta, olddelta, *deltap; 126595584Sanholt int error; 1266145132Sanholt 1267145132Sanholt if (uap->delta) { 126895584Sanholt error = copyin(uap->delta, &tv32, sizeof(tv32)); 126995584Sanholt if (error) 127095584Sanholt return (error); 127195584Sanholt CP(tv32, delta, tv_sec); 1272145132Sanholt CP(tv32, delta, tv_usec); 1273145132Sanholt deltap = δ 1274119098Sanholt } else 1275119098Sanholt deltap = NULL; 1276119098Sanholt error = kern_adjtime(td, deltap, &olddelta); 1277119098Sanholt if (uap->olddelta && error == 0) { 1278119098Sanholt CP(olddelta, tv32, tv_sec); 1279182080Srnoland CP(olddelta, tv32, tv_usec); 1280119098Sanholt error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 1281119098Sanholt } 1282119098Sanholt return (error); 1283145132Sanholt} 1284145132Sanholt 1285182080Srnoland#ifdef COMPAT_FREEBSD4 1286119098Sanholtint 1287119098Sanholtfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 1288119098Sanholt{ 1289119098Sanholt struct statfs32 s32; 1290145132Sanholt struct statfs s; 1291182080Srnoland int error; 1292119098Sanholt 1293145132Sanholt error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 1294119098Sanholt if (error) 1295119098Sanholt return (error); 1296119098Sanholt copy_statfs(&s, &s32); 1297119098Sanholt return (copyout(&s32, uap->buf, sizeof(s32))); 1298145132Sanholt} 1299119098Sanholt#endif 1300119098Sanholt 1301145132Sanholt#ifdef COMPAT_FREEBSD4 1302145132Sanholtint 1303119098Sanholtfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 1304145132Sanholt{ 1305182080Srnoland struct statfs32 s32; 1306119098Sanholt struct statfs s; 1307119098Sanholt int error; 1308119098Sanholt 1309119098Sanholt error = kern_fstatfs(td, uap->fd, &s); 1310119098Sanholt if (error) 1311119098Sanholt return (error); 1312182080Srnoland copy_statfs(&s, &s32); 131395584Sanholt return (copyout(&s32, uap->buf, sizeof(s32))); 1314182080Srnoland} 131595584Sanholt#endif 1316182080Srnoland 1317119098Sanholt#ifdef COMPAT_FREEBSD4 1318182080Srnolandint 1319182080Srnolandfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 132095584Sanholt{ 1321182080Srnoland struct statfs32 s32; 132295584Sanholt struct statfs s; 1323112015Sanholt fhandle_t fh; 1324145132Sanholt int error; 1325182080Srnoland 132695584Sanholt if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 1327145132Sanholt return (error); 132895584Sanholt error = kern_fhstatfs(td, fh, &s); 132995584Sanholt if (error) 1330182080Srnoland return (error); 133195584Sanholt copy_statfs(&s, &s32); 133295584Sanholt return (copyout(&s32, uap->buf, sizeof(s32))); 1333182080Srnoland} 133495584Sanholt#endif 133595584Sanholt 1336145132Sanholtint 133795584Sanholtfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 1338182080Srnoland{ 133995584Sanholt /* 1340145132Sanholt * Vector through to semsys if it is loaded. 1341182080Srnoland */ 134295584Sanholt return sysent[SYS_semsys].sy_call(td, uap); 134395584Sanholt} 1344145132Sanholt 1345182080Srnolandint 1346182080Srnolandfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 134795584Sanholt{ 134895584Sanholt switch (uap->which) { 134995584Sanholt case 2: 1350145132Sanholt return (freebsd32_msgsnd(td, 135195584Sanholt (struct freebsd32_msgsnd_args *)&uap->a2)); 135295584Sanholt break; 135395584Sanholt case 3: 135495584Sanholt return (freebsd32_msgrcv(td, 135595584Sanholt (struct freebsd32_msgrcv_args *)&uap->a2)); 135695584Sanholt break; 135795584Sanholt default: 1358182080Srnoland /* 135995584Sanholt * Vector through to msgsys if it is loaded. 136095584Sanholt */ 1361182080Srnoland return (sysent[SYS_msgsys].sy_call(td, uap)); 136295584Sanholt break; 1363145132Sanholt } 136495584Sanholt} 1365182080Srnoland 136695584Sanholtint 1367112015Sanholtfreebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap) 1368112015Sanholt{ 1369112015Sanholt const void *msgp; 137095584Sanholt long mtype; 137195584Sanholt int32_t mtype32; 137295584Sanholt int error; 1373182080Srnoland 1374145132Sanholt if (!SYSCALL_MODULE_PRESENT(msgsnd)) 137595584Sanholt return (nosys(td, (struct nosys_args *)uap)); 137695584Sanholt 137795584Sanholt msgp = PTRIN(uap->msgp); 137895584Sanholt if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0) 137995584Sanholt return (error); 1380182080Srnoland mtype = mtype32; 1381145132Sanholt return (kern_msgsnd(td, uap->msqid, 1382145132Sanholt (const char *)msgp + sizeof(mtype32), 1383145132Sanholt uap->msgsz, uap->msgflg, mtype)); 138495584Sanholt} 138595584Sanholt 138695584Sanholtint 138795584Sanholtfreebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap) 138895584Sanholt{ 138995584Sanholt void *msgp; 1390145132Sanholt long mtype; 139195584Sanholt int32_t mtype32; 139295584Sanholt int error; 1393145132Sanholt 139495584Sanholt if (!SYSCALL_MODULE_PRESENT(msgrcv)) 139595584Sanholt return (nosys(td, (struct nosys_args *)uap)); 139695584Sanholt 139795584Sanholt msgp = PTRIN(uap->msgp); 1398182080Srnoland if ((error = kern_msgrcv(td, uap->msqid, 1399112015Sanholt (char *)msgp + sizeof(mtype32), uap->msgsz, 1400112015Sanholt uap->msgtyp, uap->msgflg, &mtype)) != 0) 1401145132Sanholt return (error); 1402112015Sanholt mtype32 = (int32_t)mtype; 1403112015Sanholt return (copyout(&mtype32, msgp, sizeof(mtype32))); 1404112015Sanholt} 1405112015Sanholt 1406145132Sanholtint 1407112015Sanholtfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 1408112015Sanholt{ 1409112015Sanholt 1410112015Sanholt switch (uap->which) { 1411152909Sanholt case 0: { /* shmat */ 1412182080Srnoland struct shmat_args ap; 1413152909Sanholt 1414152909Sanholt ap.shmid = uap->a2; 1415112015Sanholt ap.shmaddr = PTRIN(uap->a3); 1416112015Sanholt ap.shmflg = uap->a4; 1417152909Sanholt return (sysent[SYS_shmat].sy_call(td, &ap)); 1418112015Sanholt } 1419145132Sanholt case 2: { /* shmdt */ 1420145132Sanholt struct shmdt_args ap; 1421112015Sanholt 1422112015Sanholt ap.shmaddr = PTRIN(uap->a2); 1423112015Sanholt return (sysent[SYS_shmdt].sy_call(td, &ap)); 1424145132Sanholt } 1425145132Sanholt case 3: { /* shmget */ 1426112015Sanholt struct shmget_args ap; 1427157617Sanholt 1428145132Sanholt ap.key = uap->a2; 1429157617Sanholt ap.size = uap->a3; 1430157617Sanholt ap.shmflg = uap->a4; 1431157617Sanholt return (sysent[SYS_shmget].sy_call(td, &ap)); 1432157617Sanholt } 1433157617Sanholt case 4: { /* shmctl */ 1434145132Sanholt struct freebsd32_shmctl_args ap; 1435145132Sanholt 1436145132Sanholt ap.shmid = uap->a2; 1437112015Sanholt ap.cmd = uap->a3; 1438145132Sanholt ap.buf = PTRIN(uap->a4); 1439145132Sanholt return (freebsd32_shmctl(td, &ap)); 1440112015Sanholt } 1441112015Sanholt case 1: /* oshmctl */ 1442145132Sanholt default: 1443112015Sanholt return (EINVAL); 1444112015Sanholt } 1445112015Sanholt} 144695584Sanholt 144795584Sanholtstruct ipc_perm32 { 1448182080Srnoland uint16_t cuid; 144995584Sanholt uint16_t cgid; 145095584Sanholt uint16_t uid; 1451145132Sanholt uint16_t gid; 145295584Sanholt uint16_t mode; 1453182080Srnoland uint16_t seq; 145495584Sanholt uint32_t key; 1455145132Sanholt}; 1456182080Srnolandstruct shmid_ds32 { 1457182080Srnoland struct ipc_perm32 shm_perm; 145895584Sanholt int32_t shm_segsz; 145995584Sanholt int32_t shm_lpid; 1460145132Sanholt int32_t shm_cpid; 146195584Sanholt int16_t shm_nattch; 146295584Sanholt int32_t shm_atime; 146395584Sanholt int32_t shm_dtime; 146495584Sanholt int32_t shm_ctime; 146595584Sanholt uint32_t shm_internal; 146695584Sanholt}; 146795584Sanholtstruct shm_info32 { 1468182080Srnoland int32_t used_ids; 146995584Sanholt uint32_t shm_tot; 147095584Sanholt uint32_t shm_rss; 1471145132Sanholt uint32_t shm_swp; 147295584Sanholt uint32_t swap_attempts; 1473182080Srnoland uint32_t swap_successes; 147495584Sanholt}; 1475145132Sanholtstruct shminfo32 { 147695584Sanholt uint32_t shmmax; 147795584Sanholt uint32_t shmmin; 1478119098Sanholt uint32_t shmmni; 1479119098Sanholt uint32_t shmseg; 1480182080Srnoland uint32_t shmall; 1481119098Sanholt}; 1482119098Sanholt 1483119098Sanholtint 1484119098Sanholtfreebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap) 1485119098Sanholt{ 1486182080Srnoland int error = 0; 148795584Sanholt union { 1488145132Sanholt struct shmid_ds shmid_ds; 148995584Sanholt struct shm_info shm_info; 1490182080Srnoland struct shminfo shminfo; 149195584Sanholt } u; 1492145132Sanholt union { 149395584Sanholt struct shmid_ds32 shmid_ds32; 149495584Sanholt struct shm_info32 shm_info32; 149595584Sanholt struct shminfo32 shminfo32; 149695584Sanholt } u32; 149795584Sanholt size_t sz; 149895584Sanholt 1499112015Sanholt if (uap->cmd == IPC_SET) { 1500112015Sanholt if ((error = copyin(uap->buf, &u32.shmid_ds32, 1501182080Srnoland sizeof(u32.shmid_ds32)))) 150295584Sanholt goto done; 150395584Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cuid); 150495584Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cgid); 150595584Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_perm.uid); 150695584Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_perm.gid); 150795584Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_perm.mode); 150895584Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_perm.seq); 150995584Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_perm.key); 1510112015Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_segsz); 1511112015Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_lpid); 1512112015Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_cpid); 1513112015Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_nattch); 1514145132Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_atime); 1515112015Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); 1516112015Sanholt CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); 1517112015Sanholt PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal); 1518112015Sanholt } 1519112015Sanholt 1520112015Sanholt error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); 1521145132Sanholt if (error) 1522112015Sanholt goto done; 1523112015Sanholt 1524145132Sanholt /* Cases in which we need to copyout */ 1525112015Sanholt switch (uap->cmd) { 1526112015Sanholt case IPC_INFO: 1527182080Srnoland CP(u.shminfo, u32.shminfo32, shmmax); 152895584Sanholt CP(u.shminfo, u32.shminfo32, shmmin); 1529182080Srnoland CP(u.shminfo, u32.shminfo32, shmmni); 153095584Sanholt CP(u.shminfo, u32.shminfo32, shmseg); 1531112015Sanholt CP(u.shminfo, u32.shminfo32, shmall); 1532182080Srnoland error = copyout(&u32.shminfo32, uap->buf, 1533112015Sanholt sizeof(u32.shminfo32)); 1534112015Sanholt break; 153595584Sanholt case SHM_INFO: 1536145132Sanholt CP(u.shm_info, u32.shm_info32, used_ids); 1537112015Sanholt CP(u.shm_info, u32.shm_info32, shm_rss); 153895584Sanholt CP(u.shm_info, u32.shm_info32, shm_tot); 1539112015Sanholt CP(u.shm_info, u32.shm_info32, shm_swp); 154095584Sanholt CP(u.shm_info, u32.shm_info32, swap_attempts); 1541145132Sanholt CP(u.shm_info, u32.shm_info32, swap_successes); 1542145132Sanholt error = copyout(&u32.shm_info32, uap->buf, 1543145132Sanholt sizeof(u32.shm_info32)); 1544145132Sanholt break; 1545112015Sanholt case SHM_STAT: 1546112015Sanholt case IPC_STAT: 1547182080Srnoland CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cuid); 1548182080Srnoland CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cgid); 1549182080Srnoland CP(u.shmid_ds, u32.shmid_ds32, shm_perm.uid); 1550112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_perm.gid); 1551112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_perm.mode); 1552112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_perm.seq); 1553112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_perm.key); 1554112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); 1555112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); 155695584Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); 1557112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); 1558145132Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_atime); 1559112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); 1560112015Sanholt CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); 156195584Sanholt PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal); 156295584Sanholt error = copyout(&u32.shmid_ds32, uap->buf, 1563145132Sanholt sizeof(u32.shmid_ds32)); 1564112015Sanholt break; 156595584Sanholt } 1566145132Sanholt 1567112015Sanholtdone: 1568182080Srnoland if (error) { 156995584Sanholt /* Invalidate the return value */ 1570182080Srnoland td->td_retval[0] = -1; 157195584Sanholt } 157295584Sanholt return (error); 1573182080Srnoland} 157495584Sanholt 157595584Sanholtint 1576112015Sanholtfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 157795584Sanholt{ 1578145132Sanholt struct pread_args ap; 157995584Sanholt 1580112015Sanholt ap.fd = uap->fd; 158195584Sanholt ap.buf = uap->buf; 1582112015Sanholt ap.nbyte = uap->nbyte; 1583145132Sanholt ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1584145132Sanholt return (pread(td, &ap)); 1585145132Sanholt} 158695584Sanholt 158795584Sanholtint 1588182080Srnolandfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1589182080Srnoland{ 1590182080Srnoland struct pwrite_args ap; 1591112015Sanholt 159295584Sanholt ap.fd = uap->fd; 159395584Sanholt ap.buf = uap->buf; 159495584Sanholt ap.nbyte = uap->nbyte; 159595584Sanholt ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1596112015Sanholt return (pwrite(td, &ap)); 159795584Sanholt} 159895584Sanholt 159995584Sanholtint 160095584Sanholtfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1601112015Sanholt{ 160295584Sanholt int error; 1603182080Srnoland struct lseek_args ap; 160495584Sanholt off_t pos; 1605182080Srnoland 160695584Sanholt ap.fd = uap->fd; 160795584Sanholt ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 160895584Sanholt ap.whence = uap->whence; 160995584Sanholt error = lseek(td, &ap); 1610145132Sanholt /* Expand the quad return into two parts for eax and edx */ 1611182080Srnoland pos = *(off_t *)(td->td_retval); 161295584Sanholt td->td_retval[0] = pos & 0xffffffff; /* %eax */ 161395584Sanholt td->td_retval[1] = pos >> 32; /* %edx */ 161495584Sanholt return error; 161595584Sanholt} 161695584Sanholt 161795584Sanholtint 161895584Sanholtfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 161995584Sanholt{ 162095584Sanholt struct truncate_args ap; 1621145132Sanholt 162295584Sanholt ap.path = uap->path; 162395584Sanholt ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 162495584Sanholt return (truncate(td, &ap)); 1625145132Sanholt} 162695584Sanholt 1627145132Sanholtint 1628145132Sanholtfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1629112015Sanholt{ 1630112015Sanholt struct ftruncate_args ap; 1631145132Sanholt 1632112015Sanholt ap.fd = uap->fd; 1633145132Sanholt ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 163495584Sanholt return (ftruncate(td, &ap)); 1635145132Sanholt} 1636112015Sanholt 1637112015Sanholt#ifdef COMPAT_FREEBSD6 1638112015Sanholt/* versions with the 'int pad' argument */ 1639112015Sanholtint 1640112015Sanholtfreebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap) 1641112015Sanholt{ 1642145132Sanholt struct pread_args ap; 164395584Sanholt 164495584Sanholt ap.fd = uap->fd; 164595584Sanholt ap.buf = uap->buf; 164695584Sanholt ap.nbyte = uap->nbyte; 1647145132Sanholt ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1648145132Sanholt return (pread(td, &ap)); 164995584Sanholt} 1650182080Srnoland 165195584Sanholtint 165295584Sanholtfreebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap) 1653182080Srnoland{ 1654182080Srnoland struct pwrite_args ap; 1655182080Srnoland 165695584Sanholt ap.fd = uap->fd; 165795584Sanholt ap.buf = uap->buf; 1658182080Srnoland ap.nbyte = uap->nbyte; 165995584Sanholt ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1660145132Sanholt return (pwrite(td, &ap)); 1661145132Sanholt} 1662145132Sanholt 1663182080Srnolandint 166495584Sanholtfreebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap) 1665182080Srnoland{ 166695584Sanholt int error; 1667145132Sanholt struct lseek_args ap; 1668145132Sanholt off_t pos; 1669182080Srnoland 1670145132Sanholt ap.fd = uap->fd; 1671145132Sanholt ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1672182080Srnoland ap.whence = uap->whence; 167395584Sanholt error = lseek(td, &ap); 167495584Sanholt /* Expand the quad return into two parts for eax and edx */ 167595584Sanholt pos = *(off_t *)(td->td_retval); 167695584Sanholt td->td_retval[0] = pos & 0xffffffff; /* %eax */ 167795584Sanholt td->td_retval[1] = pos >> 32; /* %edx */ 167895584Sanholt return error; 1679182080Srnoland} 168095584Sanholt 1681182080Srnolandint 168295584Sanholtfreebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap) 1683182080Srnoland{ 168495584Sanholt struct truncate_args ap; 1685182080Srnoland 168695584Sanholt ap.path = uap->path; 168795584Sanholt ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 168895584Sanholt return (truncate(td, &ap)); 1689182080Srnoland} 1690145132Sanholt 1691182080Srnolandint 1692182080Srnolandfreebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap) 169395584Sanholt{ 169495584Sanholt struct ftruncate_args ap; 169595584Sanholt 169695584Sanholt ap.fd = uap->fd; 1697182080Srnoland ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1698145132Sanholt return (ftruncate(td, &ap)); 1699182080Srnoland} 1700182080Srnoland#endif /* COMPAT_FREEBSD6 */ 170195584Sanholt 170295584Sanholtstruct sf_hdtr32 { 1703182080Srnoland uint32_t headers; 170495584Sanholt int hdr_cnt; 1705182080Srnoland uint32_t trailers; 1706182080Srnoland int trl_cnt; 170795584Sanholt}; 170895584Sanholt 170995584Sanholtstatic int 171095584Sanholtfreebsd32_do_sendfile(struct thread *td, 1711145132Sanholt struct freebsd32_sendfile_args *uap, int compat) 1712152909Sanholt{ 1713145132Sanholt struct sendfile_args ap; 1714145132Sanholt struct sf_hdtr32 hdtr32; 1715145132Sanholt struct sf_hdtr hdtr; 1716145132Sanholt struct uio *hdr_uio, *trl_uio; 1717145132Sanholt struct iovec32 *iov32; 1718145132Sanholt int error; 1719182080Srnoland 1720145132Sanholt hdr_uio = trl_uio = NULL; 1721145132Sanholt 1722145132Sanholt ap.fd = uap->fd; 1723145132Sanholt ap.s = uap->s; 1724145132Sanholt ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1725182080Srnoland ap.nbytes = uap->nbytes; 1726145132Sanholt ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */ 1727145132Sanholt ap.sbytes = uap->sbytes; 1728145132Sanholt ap.flags = uap->flags; 1729145132Sanholt 1730157617Sanholt if (uap->hdtr != NULL) { 1731148211Sanholt error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); 1732183830Srnoland if (error) 1733157617Sanholt goto out; 1734182080Srnoland PTRIN_CP(hdtr32, hdtr, headers); 1735182080Srnoland CP(hdtr32, hdtr, hdr_cnt); 1736182080Srnoland PTRIN_CP(hdtr32, hdtr, trailers); 1737182080Srnoland CP(hdtr32, hdtr, trl_cnt); 1738182080Srnoland 1739145132Sanholt if (hdtr.headers != NULL) { 1740145132Sanholt iov32 = PTRIN(hdtr32.headers); 1741157617Sanholt error = freebsd32_copyinuio(iov32, 1742145132Sanholt hdtr32.hdr_cnt, &hdr_uio); 1743145132Sanholt if (error) 1744145132Sanholt goto out; 1745182080Srnoland } 1746145132Sanholt if (hdtr.trailers != NULL) { 1747182080Srnoland iov32 = PTRIN(hdtr32.trailers); 1748162132Sanholt error = freebsd32_copyinuio(iov32, 1749182080Srnoland hdtr32.trl_cnt, &trl_uio); 1750162132Sanholt if (error) 1751182080Srnoland goto out; 1752148211Sanholt } 1753145132Sanholt } 1754182080Srnoland 1755145132Sanholt error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat); 1756145132Sanholtout: 1757145132Sanholt if (hdr_uio) 1758152909Sanholt free(hdr_uio, M_IOV); 1759152909Sanholt if (trl_uio) 1760152909Sanholt free(trl_uio, M_IOV); 1761152909Sanholt return (error); 1762145132Sanholt} 1763152909Sanholt 1764152909Sanholt#ifdef COMPAT_FREEBSD4 1765145132Sanholtint 1766145132Sanholtfreebsd4_freebsd32_sendfile(struct thread *td, 1767182080Srnoland struct freebsd4_freebsd32_sendfile_args *uap) 1768182080Srnoland{ 1769152909Sanholt return (freebsd32_do_sendfile(td, 1770152909Sanholt (struct freebsd32_sendfile_args *)uap, 1)); 1771152909Sanholt} 1772152909Sanholt#endif 1773152909Sanholt 1774152909Sanholtint 1775182080Srnolandfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1776182080Srnoland{ 1777152909Sanholt 1778152909Sanholt return (freebsd32_do_sendfile(td, uap, 0)); 1779152909Sanholt} 1780152909Sanholt 1781152909Sanholtstruct stat32 { 1782152909Sanholt dev_t st_dev; 1783152909Sanholt ino_t st_ino; 1784152909Sanholt mode_t st_mode; 1785152909Sanholt nlink_t st_nlink; 1786152909Sanholt uid_t st_uid; 1787152909Sanholt gid_t st_gid; 1788152909Sanholt dev_t st_rdev; 1789145132Sanholt struct timespec32 st_atimespec; 1790145132Sanholt struct timespec32 st_mtimespec; 1791145132Sanholt struct timespec32 st_ctimespec; 1792145132Sanholt off_t st_size; 1793145132Sanholt int64_t st_blocks; 1794145132Sanholt u_int32_t st_blksize; 1795 u_int32_t st_flags; 1796 u_int32_t st_gen; 1797 struct timespec32 st_birthtimespec; 1798 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1799 unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1800}; 1801 1802 1803CTASSERT(sizeof(struct stat32) == 96); 1804 1805static void 1806copy_stat( struct stat *in, struct stat32 *out) 1807{ 1808 CP(*in, *out, st_dev); 1809 CP(*in, *out, st_ino); 1810 CP(*in, *out, st_mode); 1811 CP(*in, *out, st_nlink); 1812 CP(*in, *out, st_uid); 1813 CP(*in, *out, st_gid); 1814 CP(*in, *out, st_rdev); 1815 TS_CP(*in, *out, st_atimespec); 1816 TS_CP(*in, *out, st_mtimespec); 1817 TS_CP(*in, *out, st_ctimespec); 1818 CP(*in, *out, st_size); 1819 CP(*in, *out, st_blocks); 1820 CP(*in, *out, st_blksize); 1821 CP(*in, *out, st_flags); 1822 CP(*in, *out, st_gen); 1823} 1824 1825int 1826freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1827{ 1828 struct stat sb; 1829 struct stat32 sb32; 1830 int error; 1831 1832 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1833 if (error) 1834 return (error); 1835 copy_stat(&sb, &sb32); 1836 error = copyout(&sb32, uap->ub, sizeof (sb32)); 1837 return (error); 1838} 1839 1840int 1841freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1842{ 1843 struct stat ub; 1844 struct stat32 ub32; 1845 int error; 1846 1847 error = kern_fstat(td, uap->fd, &ub); 1848 if (error) 1849 return (error); 1850 copy_stat(&ub, &ub32); 1851 error = copyout(&ub32, uap->ub, sizeof(ub32)); 1852 return (error); 1853} 1854 1855int 1856freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1857{ 1858 struct stat sb; 1859 struct stat32 sb32; 1860 int error; 1861 1862 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1863 if (error) 1864 return (error); 1865 copy_stat(&sb, &sb32); 1866 error = copyout(&sb32, uap->ub, sizeof (sb32)); 1867 return (error); 1868} 1869 1870/* 1871 * MPSAFE 1872 */ 1873int 1874freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1875{ 1876 int error, name[CTL_MAXNAME]; 1877 size_t j, oldlen; 1878 1879 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1880 return (EINVAL); 1881 error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1882 if (error) 1883 return (error); 1884 mtx_lock(&Giant); 1885 if (uap->oldlenp) 1886 oldlen = fuword32(uap->oldlenp); 1887 else 1888 oldlen = 0; 1889 error = userland_sysctl(td, name, uap->namelen, 1890 uap->old, &oldlen, 1, 1891 uap->new, uap->newlen, &j, SCTL_MASK32); 1892 if (error && error != ENOMEM) 1893 goto done2; 1894 if (uap->oldlenp) 1895 suword32(uap->oldlenp, j); 1896done2: 1897 mtx_unlock(&Giant); 1898 return (error); 1899} 1900 1901struct sigaction32 { 1902 u_int32_t sa_u; 1903 int sa_flags; 1904 sigset_t sa_mask; 1905}; 1906 1907CTASSERT(sizeof(struct sigaction32) == 24); 1908 1909int 1910freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1911{ 1912 struct sigaction32 s32; 1913 struct sigaction sa, osa, *sap; 1914 int error; 1915 1916 if (uap->act) { 1917 error = copyin(uap->act, &s32, sizeof(s32)); 1918 if (error) 1919 return (error); 1920 sa.sa_handler = PTRIN(s32.sa_u); 1921 CP(s32, sa, sa_flags); 1922 CP(s32, sa, sa_mask); 1923 sap = &sa; 1924 } else 1925 sap = NULL; 1926 error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1927 if (error == 0 && uap->oact != NULL) { 1928 s32.sa_u = PTROUT(osa.sa_handler); 1929 CP(osa, s32, sa_flags); 1930 CP(osa, s32, sa_mask); 1931 error = copyout(&s32, uap->oact, sizeof(s32)); 1932 } 1933 return (error); 1934} 1935 1936#ifdef COMPAT_FREEBSD4 1937int 1938freebsd4_freebsd32_sigaction(struct thread *td, 1939 struct freebsd4_freebsd32_sigaction_args *uap) 1940{ 1941 struct sigaction32 s32; 1942 struct sigaction sa, osa, *sap; 1943 int error; 1944 1945 if (uap->act) { 1946 error = copyin(uap->act, &s32, sizeof(s32)); 1947 if (error) 1948 return (error); 1949 sa.sa_handler = PTRIN(s32.sa_u); 1950 CP(s32, sa, sa_flags); 1951 CP(s32, sa, sa_mask); 1952 sap = &sa; 1953 } else 1954 sap = NULL; 1955 error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1956 if (error == 0 && uap->oact != NULL) { 1957 s32.sa_u = PTROUT(osa.sa_handler); 1958 CP(osa, s32, sa_flags); 1959 CP(osa, s32, sa_mask); 1960 error = copyout(&s32, uap->oact, sizeof(s32)); 1961 } 1962 return (error); 1963} 1964#endif 1965 1966#ifdef COMPAT_43 1967struct osigaction32 { 1968 u_int32_t sa_u; 1969 osigset_t sa_mask; 1970 int sa_flags; 1971}; 1972 1973#define ONSIG 32 1974 1975int 1976ofreebsd32_sigaction(struct thread *td, 1977 struct ofreebsd32_sigaction_args *uap) 1978{ 1979 struct osigaction32 s32; 1980 struct sigaction sa, osa, *sap; 1981 int error; 1982 1983 if (uap->signum <= 0 || uap->signum >= ONSIG) 1984 return (EINVAL); 1985 1986 if (uap->nsa) { 1987 error = copyin(uap->nsa, &s32, sizeof(s32)); 1988 if (error) 1989 return (error); 1990 sa.sa_handler = PTRIN(s32.sa_u); 1991 CP(s32, sa, sa_flags); 1992 OSIG2SIG(s32.sa_mask, sa.sa_mask); 1993 sap = &sa; 1994 } else 1995 sap = NULL; 1996 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 1997 if (error == 0 && uap->osa != NULL) { 1998 s32.sa_u = PTROUT(osa.sa_handler); 1999 CP(osa, s32, sa_flags); 2000 SIG2OSIG(osa.sa_mask, s32.sa_mask); 2001 error = copyout(&s32, uap->osa, sizeof(s32)); 2002 } 2003 return (error); 2004} 2005 2006int 2007ofreebsd32_sigprocmask(struct thread *td, 2008 struct ofreebsd32_sigprocmask_args *uap) 2009{ 2010 sigset_t set, oset; 2011 int error; 2012 2013 OSIG2SIG(uap->mask, set); 2014 error = kern_sigprocmask(td, uap->how, &set, &oset, 1); 2015 SIG2OSIG(oset, td->td_retval[0]); 2016 return (error); 2017} 2018 2019int 2020ofreebsd32_sigpending(struct thread *td, 2021 struct ofreebsd32_sigpending_args *uap) 2022{ 2023 struct proc *p = td->td_proc; 2024 sigset_t siglist; 2025 2026 PROC_LOCK(p); 2027 siglist = p->p_siglist; 2028 SIGSETOR(siglist, td->td_siglist); 2029 PROC_UNLOCK(p); 2030 SIG2OSIG(siglist, td->td_retval[0]); 2031 return (0); 2032} 2033 2034struct sigvec32 { 2035 u_int32_t sv_handler; 2036 int sv_mask; 2037 int sv_flags; 2038}; 2039 2040int 2041ofreebsd32_sigvec(struct thread *td, 2042 struct ofreebsd32_sigvec_args *uap) 2043{ 2044 struct sigvec32 vec; 2045 struct sigaction sa, osa, *sap; 2046 int error; 2047 2048 if (uap->signum <= 0 || uap->signum >= ONSIG) 2049 return (EINVAL); 2050 2051 if (uap->nsv) { 2052 error = copyin(uap->nsv, &vec, sizeof(vec)); 2053 if (error) 2054 return (error); 2055 sa.sa_handler = PTRIN(vec.sv_handler); 2056 OSIG2SIG(vec.sv_mask, sa.sa_mask); 2057 sa.sa_flags = vec.sv_flags; 2058 sa.sa_flags ^= SA_RESTART; 2059 sap = &sa; 2060 } else 2061 sap = NULL; 2062 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 2063 if (error == 0 && uap->osv != NULL) { 2064 vec.sv_handler = PTROUT(osa.sa_handler); 2065 SIG2OSIG(osa.sa_mask, vec.sv_mask); 2066 vec.sv_flags = osa.sa_flags; 2067 vec.sv_flags &= ~SA_NOCLDWAIT; 2068 vec.sv_flags ^= SA_RESTART; 2069 error = copyout(&vec, uap->osv, sizeof(vec)); 2070 } 2071 return (error); 2072} 2073 2074int 2075ofreebsd32_sigblock(struct thread *td, 2076 struct ofreebsd32_sigblock_args *uap) 2077{ 2078 struct proc *p = td->td_proc; 2079 sigset_t set; 2080 2081 OSIG2SIG(uap->mask, set); 2082 SIG_CANTMASK(set); 2083 PROC_LOCK(p); 2084 SIG2OSIG(td->td_sigmask, td->td_retval[0]); 2085 SIGSETOR(td->td_sigmask, set); 2086 PROC_UNLOCK(p); 2087 return (0); 2088} 2089 2090int 2091ofreebsd32_sigsetmask(struct thread *td, 2092 struct ofreebsd32_sigsetmask_args *uap) 2093{ 2094 struct proc *p = td->td_proc; 2095 sigset_t set; 2096 2097 OSIG2SIG(uap->mask, set); 2098 SIG_CANTMASK(set); 2099 PROC_LOCK(p); 2100 SIG2OSIG(td->td_sigmask, td->td_retval[0]); 2101 SIGSETLO(td->td_sigmask, set); 2102 signotify(td); 2103 PROC_UNLOCK(p); 2104 return (0); 2105} 2106 2107int 2108ofreebsd32_sigsuspend(struct thread *td, 2109 struct ofreebsd32_sigsuspend_args *uap) 2110{ 2111 struct proc *p = td->td_proc; 2112 sigset_t mask; 2113 2114 PROC_LOCK(p); 2115 td->td_oldsigmask = td->td_sigmask; 2116 td->td_pflags |= TDP_OLDMASK; 2117 OSIG2SIG(uap->mask, mask); 2118 SIG_CANTMASK(mask); 2119 SIGSETLO(td->td_sigmask, mask); 2120 signotify(td); 2121 while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) 2122 /* void */; 2123 PROC_UNLOCK(p); 2124 /* always return EINTR rather than ERESTART... */ 2125 return (EINTR); 2126} 2127 2128struct sigstack32 { 2129 u_int32_t ss_sp; 2130 int ss_onstack; 2131}; 2132 2133int 2134ofreebsd32_sigstack(struct thread *td, 2135 struct ofreebsd32_sigstack_args *uap) 2136{ 2137 struct sigstack32 s32; 2138 struct sigstack nss, oss; 2139 int error = 0, unss; 2140 2141 if (uap->nss != NULL) { 2142 error = copyin(uap->nss, &s32, sizeof(s32)); 2143 if (error) 2144 return (error); 2145 nss.ss_sp = PTRIN(s32.ss_sp); 2146 CP(s32, nss, ss_onstack); 2147 unss = 1; 2148 } else { 2149 unss = 0; 2150 } 2151 oss.ss_sp = td->td_sigstk.ss_sp; 2152 oss.ss_onstack = sigonstack(cpu_getstack(td)); 2153 if (unss) { 2154 td->td_sigstk.ss_sp = nss.ss_sp; 2155 td->td_sigstk.ss_size = 0; 2156 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK); 2157 td->td_pflags |= TDP_ALTSTACK; 2158 } 2159 if (uap->oss != NULL) { 2160 s32.ss_sp = PTROUT(oss.ss_sp); 2161 CP(oss, s32, ss_onstack); 2162 error = copyout(&s32, uap->oss, sizeof(s32)); 2163 } 2164 return (error); 2165} 2166#endif 2167 2168int 2169freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 2170{ 2171 struct timespec32 rmt32, rqt32; 2172 struct timespec rmt, rqt; 2173 int error; 2174 2175 error = copyin(uap->rqtp, &rqt32, sizeof(rqt32)); 2176 if (error) 2177 return (error); 2178 2179 CP(rqt32, rqt, tv_sec); 2180 CP(rqt32, rqt, tv_nsec); 2181 2182 if (uap->rmtp && 2183 !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 2184 return (EFAULT); 2185 error = kern_nanosleep(td, &rqt, &rmt); 2186 if (error && uap->rmtp) { 2187 int error2; 2188 2189 CP(rmt, rmt32, tv_sec); 2190 CP(rmt, rmt32, tv_nsec); 2191 2192 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32)); 2193 if (error2) 2194 error = error2; 2195 } 2196 return (error); 2197} 2198 2199int 2200freebsd32_clock_gettime(struct thread *td, 2201 struct freebsd32_clock_gettime_args *uap) 2202{ 2203 struct timespec ats; 2204 struct timespec32 ats32; 2205 int error; 2206 2207 error = kern_clock_gettime(td, uap->clock_id, &ats); 2208 if (error == 0) { 2209 CP(ats, ats32, tv_sec); 2210 CP(ats, ats32, tv_nsec); 2211 error = copyout(&ats32, uap->tp, sizeof(ats32)); 2212 } 2213 return (error); 2214} 2215 2216int 2217freebsd32_clock_settime(struct thread *td, 2218 struct freebsd32_clock_settime_args *uap) 2219{ 2220 struct timespec ats; 2221 struct timespec32 ats32; 2222 int error; 2223 2224 error = copyin(uap->tp, &ats32, sizeof(ats32)); 2225 if (error) 2226 return (error); 2227 CP(ats32, ats, tv_sec); 2228 CP(ats32, ats, tv_nsec); 2229 2230 return (kern_clock_settime(td, uap->clock_id, &ats)); 2231} 2232 2233int 2234freebsd32_clock_getres(struct thread *td, 2235 struct freebsd32_clock_getres_args *uap) 2236{ 2237 struct timespec ts; 2238 struct timespec32 ts32; 2239 int error; 2240 2241 if (uap->tp == NULL) 2242 return (0); 2243 error = kern_clock_getres(td, uap->clock_id, &ts); 2244 if (error == 0) { 2245 CP(ts, ts32, tv_sec); 2246 CP(ts, ts32, tv_nsec); 2247 error = copyout(&ts32, uap->tp, sizeof(ts32)); 2248 } 2249 return (error); 2250} 2251 2252int 2253freebsd32_thr_new(struct thread *td, 2254 struct freebsd32_thr_new_args *uap) 2255{ 2256 struct thr_param32 param32; 2257 struct thr_param param; 2258 int error; 2259 2260 if (uap->param_size < 0 || 2261 uap->param_size > sizeof(struct thr_param32)) 2262 return (EINVAL); 2263 bzero(¶m, sizeof(struct thr_param)); 2264 bzero(¶m32, sizeof(struct thr_param32)); 2265 error = copyin(uap->param, ¶m32, uap->param_size); 2266 if (error != 0) 2267 return (error); 2268 param.start_func = PTRIN(param32.start_func); 2269 param.arg = PTRIN(param32.arg); 2270 param.stack_base = PTRIN(param32.stack_base); 2271 param.stack_size = param32.stack_size; 2272 param.tls_base = PTRIN(param32.tls_base); 2273 param.tls_size = param32.tls_size; 2274 param.child_tid = PTRIN(param32.child_tid); 2275 param.parent_tid = PTRIN(param32.parent_tid); 2276 param.flags = param32.flags; 2277 param.rtp = PTRIN(param32.rtp); 2278 param.spare[0] = PTRIN(param32.spare[0]); 2279 param.spare[1] = PTRIN(param32.spare[1]); 2280 param.spare[2] = PTRIN(param32.spare[2]); 2281 2282 return (kern_thr_new(td, ¶m)); 2283} 2284 2285int 2286freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap) 2287{ 2288 struct timespec32 ts32; 2289 struct timespec ts, *tsp; 2290 int error; 2291 2292 error = 0; 2293 tsp = NULL; 2294 if (uap->timeout != NULL) { 2295 error = copyin((const void *)uap->timeout, (void *)&ts32, 2296 sizeof(struct timespec32)); 2297 if (error != 0) 2298 return (error); 2299 ts.tv_sec = ts32.tv_sec; 2300 ts.tv_nsec = ts32.tv_nsec; 2301 tsp = &ts; 2302 } 2303 return (kern_thr_suspend(td, tsp)); 2304} 2305 2306void 2307siginfo_to_siginfo32(siginfo_t *src, struct siginfo32 *dst) 2308{ 2309 bzero(dst, sizeof(*dst)); 2310 dst->si_signo = src->si_signo; 2311 dst->si_errno = src->si_errno; 2312 dst->si_code = src->si_code; 2313 dst->si_pid = src->si_pid; 2314 dst->si_uid = src->si_uid; 2315 dst->si_status = src->si_status; 2316 dst->si_addr = dst->si_addr; 2317 dst->si_value.sigval_int = src->si_value.sival_int; 2318 dst->si_timerid = src->si_timerid; 2319 dst->si_overrun = src->si_overrun; 2320} 2321 2322int 2323freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap) 2324{ 2325 struct timespec32 ts32; 2326 struct timespec ts; 2327 struct timespec *timeout; 2328 sigset_t set; 2329 ksiginfo_t ksi; 2330 struct siginfo32 si32; 2331 int error; 2332 2333 if (uap->timeout) { 2334 error = copyin(uap->timeout, &ts32, sizeof(ts32)); 2335 if (error) 2336 return (error); 2337 ts.tv_sec = ts32.tv_sec; 2338 ts.tv_nsec = ts32.tv_nsec; 2339 timeout = &ts; 2340 } else 2341 timeout = NULL; 2342 2343 error = copyin(uap->set, &set, sizeof(set)); 2344 if (error) 2345 return (error); 2346 2347 error = kern_sigtimedwait(td, set, &ksi, timeout); 2348 if (error) 2349 return (error); 2350 2351 if (uap->info) { 2352 siginfo_to_siginfo32(&ksi.ksi_info, &si32); 2353 error = copyout(&si32, uap->info, sizeof(struct siginfo32)); 2354 } 2355 2356 if (error == 0) 2357 td->td_retval[0] = ksi.ksi_signo; 2358 return (error); 2359} 2360 2361/* 2362 * MPSAFE 2363 */ 2364int 2365freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap) 2366{ 2367 ksiginfo_t ksi; 2368 struct siginfo32 si32; 2369 sigset_t set; 2370 int error; 2371 2372 error = copyin(uap->set, &set, sizeof(set)); 2373 if (error) 2374 return (error); 2375 2376 error = kern_sigtimedwait(td, set, &ksi, NULL); 2377 if (error) 2378 return (error); 2379 2380 if (uap->info) { 2381 siginfo_to_siginfo32(&ksi.ksi_info, &si32); 2382 error = copyout(&si32, uap->info, sizeof(struct siginfo32)); 2383 } 2384 if (error == 0) 2385 td->td_retval[0] = ksi.ksi_signo; 2386 return (error); 2387} 2388 2389#if 0 2390 2391int 2392freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 2393{ 2394 int error; 2395 struct yyy32 *p32, s32; 2396 struct yyy *p = NULL, s; 2397 2398 if (uap->zzz) { 2399 error = copyin(uap->zzz, &s32, sizeof(s32)); 2400 if (error) 2401 return (error); 2402 /* translate in */ 2403 p = &s; 2404 } 2405 error = kern_xxx(td, p); 2406 if (error) 2407 return (error); 2408 if (uap->zzz) { 2409 /* translate out */ 2410 error = copyout(&s32, p32, sizeof(s32)); 2411 } 2412 return (error); 2413} 2414 2415#endif 2416