freebsd32_misc.c revision 150883
1100384Speter/*- 2100384Speter * Copyright (c) 2002 Doug Rabson 3100384Speter * All rights reserved. 4100384Speter * 5100384Speter * Redistribution and use in source and binary forms, with or without 6100384Speter * modification, are permitted provided that the following conditions 7100384Speter * are met: 8100384Speter * 1. Redistributions of source code must retain the above copyright 9100384Speter * notice, this list of conditions and the following disclaimer. 10100384Speter * 2. Redistributions in binary form must reproduce the above copyright 11100384Speter * notice, this list of conditions and the following disclaimer in the 12100384Speter * documentation and/or other materials provided with the distribution. 13100384Speter * 14100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17100384Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24100384Speter * SUCH DAMAGE. 25100384Speter */ 26100384Speter 27118031Sobrien#include <sys/cdefs.h> 28118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 150883 2005-10-03 18:34:17Z jhb $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31104738Speter 32100384Speter#include <sys/param.h> 33100384Speter#include <sys/systm.h> 34100384Speter#include <sys/bus.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/filedesc.h> 38123746Speter#include <sys/namei.h> 39100384Speter#include <sys/imgact.h> 40100384Speter#include <sys/kernel.h> 41100384Speter#include <sys/lock.h> 42100384Speter#include <sys/malloc.h> 43100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 44100384Speter#include <sys/mman.h> 45100384Speter#include <sys/module.h> 46100384Speter#include <sys/mount.h> 47100384Speter#include <sys/mutex.h> 48100384Speter#include <sys/namei.h> 49100384Speter#include <sys/param.h> 50100384Speter#include <sys/proc.h> 51100384Speter#include <sys/reboot.h> 52100384Speter#include <sys/resource.h> 53100384Speter#include <sys/resourcevar.h> 54100384Speter#include <sys/selinfo.h> 55146950Sps#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ 56100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 57100384Speter#include <sys/signal.h> 58100384Speter#include <sys/signalvar.h> 59100384Speter#include <sys/socket.h> 60100384Speter#include <sys/socketvar.h> 61100384Speter#include <sys/stat.h> 62150883Sjhb#include <sys/syscall.h> 63113859Sjhb#include <sys/syscallsubr.h> 64100384Speter#include <sys/sysctl.h> 65100384Speter#include <sys/sysent.h> 66100384Speter#include <sys/sysproto.h> 67100384Speter#include <sys/systm.h> 68100384Speter#include <sys/unistd.h> 69100384Speter#include <sys/vnode.h> 70127140Sjhb#include <sys/wait.h> 71100384Speter 72100384Speter#include <vm/vm.h> 73100384Speter#include <vm/vm_kern.h> 74100384Speter#include <vm/vm_param.h> 75100384Speter#include <vm/pmap.h> 76100384Speter#include <vm/vm_map.h> 77100384Speter#include <vm/vm_object.h> 78100384Speter#include <vm/vm_extern.h> 79100384Speter 80119333Speter#include <compat/freebsd32/freebsd32_util.h> 81119333Speter#include <compat/freebsd32/freebsd32.h> 82119333Speter#include <compat/freebsd32/freebsd32_proto.h> 83100384Speter 84121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 85121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 86121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 87121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 88121719Speter 89100384Speterint 90119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 91100384Speter{ 92127140Sjhb int error, status; 93127140Sjhb struct rusage32 ru32; 94136152Sjhb struct rusage ru, *rup; 95100384Speter 96136152Sjhb if (uap->rusage != NULL) 97136152Sjhb rup = &ru; 98136152Sjhb else 99136152Sjhb rup = NULL; 100136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 101100384Speter if (error) 102100384Speter return (error); 103127140Sjhb if (uap->status != NULL) 104127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 105127140Sjhb if (uap->rusage != NULL && error == 0) { 106100384Speter TV_CP(ru, ru32, ru_utime); 107100384Speter TV_CP(ru, ru32, ru_stime); 108100384Speter CP(ru, ru32, ru_maxrss); 109100384Speter CP(ru, ru32, ru_ixrss); 110100384Speter CP(ru, ru32, ru_idrss); 111100384Speter CP(ru, ru32, ru_isrss); 112100384Speter CP(ru, ru32, ru_minflt); 113100384Speter CP(ru, ru32, ru_majflt); 114100384Speter CP(ru, ru32, ru_nswap); 115100384Speter CP(ru, ru32, ru_inblock); 116100384Speter CP(ru, ru32, ru_oublock); 117100384Speter CP(ru, ru32, ru_msgsnd); 118100384Speter CP(ru, ru32, ru_msgrcv); 119100384Speter CP(ru, ru32, ru_nsignals); 120100384Speter CP(ru, ru32, ru_nvcsw); 121100384Speter CP(ru, ru32, ru_nivcsw); 122127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 123100384Speter } 124100384Speter return (error); 125100384Speter} 126100384Speter 127128597Smarcel#ifdef COMPAT_FREEBSD4 128100384Speterstatic void 129100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 130100384Speter{ 131100384Speter CP(*in, *out, f_bsize); 132100384Speter CP(*in, *out, f_iosize); 133100384Speter CP(*in, *out, f_blocks); 134100384Speter CP(*in, *out, f_bfree); 135100384Speter CP(*in, *out, f_bavail); 136100384Speter CP(*in, *out, f_files); 137100384Speter CP(*in, *out, f_ffree); 138100384Speter CP(*in, *out, f_fsid); 139100384Speter CP(*in, *out, f_owner); 140100384Speter CP(*in, *out, f_type); 141100384Speter CP(*in, *out, f_flags); 142100384Speter CP(*in, *out, f_flags); 143100384Speter CP(*in, *out, f_syncwrites); 144100384Speter CP(*in, *out, f_asyncwrites); 145100384Speter bcopy(in->f_fstypename, 146100384Speter out->f_fstypename, MFSNAMELEN); 147100384Speter bcopy(in->f_mntonname, 148128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 149100384Speter CP(*in, *out, f_syncreads); 150100384Speter CP(*in, *out, f_asyncreads); 151100384Speter bcopy(in->f_mntfromname, 152128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 153100384Speter} 154128597Smarcel#endif 155100384Speter 156128597Smarcel#ifdef COMPAT_FREEBSD4 157100384Speterint 158128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 159100384Speter{ 160147178Spjd struct statfs *buf, *sp; 161147178Spjd struct statfs32 stat32; 162147178Spjd size_t count, size; 163100384Speter int error; 164100384Speter 165147178Spjd count = uap->bufsize / sizeof(struct statfs32); 166147178Spjd size = count * sizeof(struct statfs); 167147302Spjd error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 168147302Spjd if (size > 0) { 169100384Speter count = td->td_retval[0]; 170147178Spjd sp = buf; 171147178Spjd while (count > 0 && error == 0) { 172147178Spjd copy_statfs(sp, &stat32); 173147178Spjd error = copyout(&stat32, uap->buf, sizeof(stat32)); 174147178Spjd sp++; 175147178Spjd uap->buf++; 176147178Spjd count--; 177100384Speter } 178147178Spjd free(buf, M_TEMP); 179100384Speter } 180100384Speter return (error); 181100384Speter} 182128597Smarcel#endif 183100384Speter 184100384Speterstruct sigaltstack32 { 185100384Speter u_int32_t ss_sp; 186100384Speter u_int32_t ss_size; 187100384Speter int ss_flags; 188100384Speter}; 189100384Speter 190121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 191121719Speter 192100384Speterint 193119333Speterfreebsd32_sigaltstack(struct thread *td, 194119333Speter struct freebsd32_sigaltstack_args *uap) 195100384Speter{ 196113859Sjhb struct sigaltstack32 s32; 197113859Sjhb struct sigaltstack ss, oss, *ssp; 198100384Speter int error; 199100384Speter 200113859Sjhb if (uap->ss != NULL) { 201113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 202100384Speter if (error) 203100384Speter return (error); 204113859Sjhb PTRIN_CP(s32, ss, ss_sp); 205113859Sjhb CP(s32, ss, ss_size); 206113859Sjhb CP(s32, ss, ss_flags); 207113859Sjhb ssp = &ss; 208113859Sjhb } else 209113859Sjhb ssp = NULL; 210113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 211113859Sjhb if (error == 0 && uap->oss != NULL) { 212113859Sjhb PTROUT_CP(oss, s32, ss_sp); 213113859Sjhb CP(oss, s32, ss_size); 214113859Sjhb CP(oss, s32, ss_flags); 215113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 216100384Speter } 217100384Speter return (error); 218100384Speter} 219100384Speter 220142059Sjhb/* 221142059Sjhb * Custom version of exec_copyin_args() so that we can translate 222142059Sjhb * the pointers. 223142059Sjhb */ 224142059Sjhbstatic int 225142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 226142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 227100384Speter{ 228142059Sjhb char *argp, *envp; 229142059Sjhb u_int32_t *p32, arg; 230142059Sjhb size_t length; 231100384Speter int error; 232100384Speter 233142059Sjhb bzero(args, sizeof(*args)); 234142059Sjhb if (argv == NULL) 235142059Sjhb return (EFAULT); 236100384Speter 237142059Sjhb /* 238142059Sjhb * Allocate temporary demand zeroed space for argument and 239142059Sjhb * environment strings 240142059Sjhb */ 241147588Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, 242147588Sjhb PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 243142059Sjhb if (args->buf == NULL) 244142059Sjhb return (ENOMEM); 245142059Sjhb args->begin_argv = args->buf; 246142059Sjhb args->endp = args->begin_argv; 247142059Sjhb args->stringspace = ARG_MAX; 248142059Sjhb 249142059Sjhb args->fname = args->buf + ARG_MAX; 250142059Sjhb 251142059Sjhb /* 252142059Sjhb * Copy the file name. 253142059Sjhb */ 254142059Sjhb error = (segflg == UIO_SYSSPACE) ? 255142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 256142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 257142059Sjhb if (error != 0) 258142059Sjhb return (error); 259142059Sjhb 260142059Sjhb /* 261142059Sjhb * extract arguments first 262142059Sjhb */ 263142059Sjhb p32 = argv; 264142059Sjhb for (;;) { 265142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 266142059Sjhb if (error) 267142059Sjhb return (error); 268142059Sjhb if (arg == 0) 269142059Sjhb break; 270142059Sjhb argp = PTRIN(arg); 271142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 272142059Sjhb if (error) { 273142059Sjhb if (error == ENAMETOOLONG) 274142059Sjhb return (E2BIG); 275142059Sjhb else 276142059Sjhb return (error); 277142059Sjhb } 278142059Sjhb args->stringspace -= length; 279142059Sjhb args->endp += length; 280142059Sjhb args->argc++; 281100384Speter } 282142059Sjhb 283142059Sjhb args->begin_envv = args->endp; 284142059Sjhb 285142059Sjhb /* 286142059Sjhb * extract environment strings 287142059Sjhb */ 288142059Sjhb if (envv) { 289142059Sjhb p32 = envv; 290142059Sjhb for (;;) { 291100384Speter error = copyin(p32++, &arg, sizeof(arg)); 292100384Speter if (error) 293142059Sjhb return (error); 294142059Sjhb if (arg == 0) 295142059Sjhb break; 296142059Sjhb envp = PTRIN(arg); 297142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 298142059Sjhb &length); 299142059Sjhb if (error) { 300142059Sjhb if (error == ENAMETOOLONG) 301142059Sjhb return (E2BIG); 302142059Sjhb else 303142059Sjhb return (error); 304142059Sjhb } 305142059Sjhb args->stringspace -= length; 306142059Sjhb args->endp += length; 307142059Sjhb args->envc++; 308142059Sjhb } 309100384Speter } 310100384Speter 311142059Sjhb return (0); 312100384Speter} 313100384Speter 314142059Sjhbint 315142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 316142059Sjhb{ 317142059Sjhb struct image_args eargs; 318142059Sjhb int error; 319142059Sjhb 320142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 321142059Sjhb uap->argv, uap->envv); 322142059Sjhb if (error == 0) 323142059Sjhb error = kern_execve(td, &eargs, NULL); 324142059Sjhb exec_free_args(&eargs); 325142059Sjhb return (error); 326142059Sjhb} 327142059Sjhb 328114987Speter#ifdef __ia64__ 329100384Speterstatic int 330119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 331119333Speter int prot, int fd, off_t pos) 332100384Speter{ 333100384Speter vm_map_t map; 334100384Speter vm_map_entry_t entry; 335100384Speter int rv; 336100384Speter 337100384Speter map = &td->td_proc->p_vmspace->vm_map; 338100384Speter if (fd != -1) 339100384Speter prot |= VM_PROT_WRITE; 340100384Speter 341100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 342100384Speter if ((entry->protection & prot) != prot) { 343100384Speter rv = vm_map_protect(map, 344100384Speter trunc_page(start), 345100384Speter round_page(end), 346100384Speter entry->protection | prot, 347100384Speter FALSE); 348100384Speter if (rv != KERN_SUCCESS) 349100384Speter return (EINVAL); 350100384Speter } 351100384Speter } else { 352100384Speter vm_offset_t addr = trunc_page(start); 353100384Speter rv = vm_map_find(map, 0, 0, 354100384Speter &addr, PAGE_SIZE, FALSE, prot, 355100384Speter VM_PROT_ALL, 0); 356100384Speter if (rv != KERN_SUCCESS) 357100384Speter return (EINVAL); 358100384Speter } 359100384Speter 360100384Speter if (fd != -1) { 361100384Speter struct pread_args r; 362107849Salfred r.fd = fd; 363107849Salfred r.buf = (void *) start; 364107849Salfred r.nbyte = end - start; 365107849Salfred r.offset = pos; 366100384Speter return (pread(td, &r)); 367100384Speter } else { 368100384Speter while (start < end) { 369100384Speter subyte((void *) start, 0); 370100384Speter start++; 371100384Speter } 372100384Speter return (0); 373100384Speter } 374100384Speter} 375114987Speter#endif 376100384Speter 377100384Speterint 378119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 379100384Speter{ 380100384Speter struct mmap_args ap; 381107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 382107849Salfred vm_size_t len = uap->len; 383107849Salfred int prot = uap->prot; 384107849Salfred int flags = uap->flags; 385107849Salfred int fd = uap->fd; 386107849Salfred off_t pos = (uap->poslo 387107849Salfred | ((off_t)uap->poshi << 32)); 388114987Speter#ifdef __ia64__ 389100384Speter vm_size_t pageoff; 390100384Speter int error; 391100384Speter 392100384Speter /* 393100384Speter * Attempt to handle page size hassles. 394100384Speter */ 395100384Speter pageoff = (pos & PAGE_MASK); 396100384Speter if (flags & MAP_FIXED) { 397100384Speter vm_offset_t start, end; 398100384Speter start = addr; 399100384Speter end = addr + len; 400100384Speter 401147964Sjhb mtx_lock(&Giant); 402100384Speter if (start != trunc_page(start)) { 403119333Speter error = freebsd32_mmap_partial(td, start, 404119333Speter round_page(start), prot, 405119333Speter fd, pos); 406100384Speter if (fd != -1) 407100384Speter pos += round_page(start) - start; 408100384Speter start = round_page(start); 409100384Speter } 410100384Speter if (end != round_page(end)) { 411100384Speter vm_offset_t t = trunc_page(end); 412119333Speter error = freebsd32_mmap_partial(td, t, end, 413100384Speter prot, fd, 414100384Speter pos + t - start); 415100384Speter end = trunc_page(end); 416100384Speter } 417100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 418100384Speter /* 419100384Speter * We can't map this region at all. The specified 420100384Speter * address doesn't have the same alignment as the file 421100384Speter * position. Fake the mapping by simply reading the 422100384Speter * entire region into memory. First we need to make 423100384Speter * sure the region exists. 424100384Speter */ 425100384Speter vm_map_t map; 426100384Speter struct pread_args r; 427100384Speter int rv; 428100384Speter 429100384Speter prot |= VM_PROT_WRITE; 430100384Speter map = &td->td_proc->p_vmspace->vm_map; 431100384Speter rv = vm_map_remove(map, start, end); 432147964Sjhb if (rv != KERN_SUCCESS) { 433147964Sjhb mtx_unlock(&Giant); 434100384Speter return (EINVAL); 435147964Sjhb } 436100384Speter rv = vm_map_find(map, 0, 0, 437100384Speter &start, end - start, FALSE, 438100384Speter prot, VM_PROT_ALL, 0); 439147964Sjhb mtx_unlock(&Giant); 440100384Speter if (rv != KERN_SUCCESS) 441100384Speter return (EINVAL); 442107849Salfred r.fd = fd; 443107849Salfred r.buf = (void *) start; 444107849Salfred r.nbyte = end - start; 445107849Salfred r.offset = pos; 446100384Speter error = pread(td, &r); 447100384Speter if (error) 448100384Speter return (error); 449100384Speter 450100384Speter td->td_retval[0] = addr; 451100384Speter return (0); 452100384Speter } 453147964Sjhb mtx_unlock(&Giant); 454100384Speter if (end == start) { 455100384Speter /* 456100384Speter * After dealing with the ragged ends, there 457100384Speter * might be none left. 458100384Speter */ 459100384Speter td->td_retval[0] = addr; 460100384Speter return (0); 461100384Speter } 462100384Speter addr = start; 463100384Speter len = end - start; 464100384Speter } 465114987Speter#endif 466100384Speter 467107849Salfred ap.addr = (void *) addr; 468107849Salfred ap.len = len; 469107849Salfred ap.prot = prot; 470107849Salfred ap.flags = flags; 471107849Salfred ap.fd = fd; 472107849Salfred ap.pos = pos; 473100384Speter 474100384Speter return (mmap(td, &ap)); 475100384Speter} 476100384Speter 477100384Speterstruct itimerval32 { 478100384Speter struct timeval32 it_interval; 479100384Speter struct timeval32 it_value; 480100384Speter}; 481100384Speter 482121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 483121719Speter 484100384Speterint 485119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 486100384Speter{ 487142059Sjhb struct itimerval itv, oitv, *itvp; 488142059Sjhb struct itimerval32 i32; 489100384Speter int error; 490100384Speter 491142059Sjhb if (uap->itv != NULL) { 492142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 493100384Speter if (error) 494100384Speter return (error); 495142059Sjhb TV_CP(i32, itv, it_interval); 496142059Sjhb TV_CP(i32, itv, it_value); 497142059Sjhb itvp = &itv; 498142059Sjhb } else 499142059Sjhb itvp = NULL; 500142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 501142059Sjhb if (error || uap->oitv == NULL) 502100384Speter return (error); 503142059Sjhb TV_CP(oitv, i32, it_interval); 504142059Sjhb TV_CP(oitv, i32, it_value); 505142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 506100384Speter} 507100384Speter 508100384Speterint 509125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 510125171Speter{ 511142059Sjhb struct itimerval itv; 512142059Sjhb struct itimerval32 i32; 513125171Speter int error; 514125171Speter 515142059Sjhb error = kern_getitimer(td, uap->which, &itv); 516142059Sjhb if (error || uap->itv == NULL) 517125171Speter return (error); 518142059Sjhb TV_CP(itv, i32, it_interval); 519142059Sjhb TV_CP(itv, i32, it_value); 520142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 521125171Speter} 522125171Speter 523125171Speterint 524119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 525100384Speter{ 526142059Sjhb struct timeval32 tv32; 527142059Sjhb struct timeval tv, *tvp; 528100384Speter int error; 529100384Speter 530142059Sjhb if (uap->tv != NULL) { 531142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 532100384Speter if (error) 533100384Speter return (error); 534142059Sjhb CP(tv32, tv, tv_sec); 535142059Sjhb CP(tv32, tv, tv_usec); 536142059Sjhb tvp = &tv; 537142059Sjhb } else 538142059Sjhb tvp = NULL; 539100384Speter /* 540100384Speter * XXX big-endian needs to convert the fd_sets too. 541142059Sjhb * XXX Do pointers need PTRIN()? 542100384Speter */ 543142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 544100384Speter} 545100384Speter 546114987Speterstruct kevent32 { 547114987Speter u_int32_t ident; /* identifier for this event */ 548114987Speter short filter; /* filter for event */ 549114987Speter u_short flags; 550114987Speter u_int fflags; 551114987Speter int32_t data; 552114987Speter u_int32_t udata; /* opaque user data identifier */ 553114987Speter}; 554114987Speter 555121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 556146950Spsstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 557146950Spsstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 558121719Speter 559146950Sps/* 560146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist. 561146950Sps */ 562146950Spsstatic int 563146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 564146950Sps{ 565146950Sps struct freebsd32_kevent_args *uap; 566146950Sps struct kevent32 ks32[KQ_NEVENTS]; 567146950Sps int i, error = 0; 568146950Sps 569146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 570146950Sps uap = (struct freebsd32_kevent_args *)arg; 571146950Sps 572146950Sps for (i = 0; i < count; i++) { 573146950Sps CP(kevp[i], ks32[i], ident); 574146950Sps CP(kevp[i], ks32[i], filter); 575146950Sps CP(kevp[i], ks32[i], flags); 576146950Sps CP(kevp[i], ks32[i], fflags); 577146950Sps CP(kevp[i], ks32[i], data); 578146950Sps PTROUT_CP(kevp[i], ks32[i], udata); 579146950Sps } 580146950Sps error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 581146950Sps if (error == 0) 582146950Sps uap->eventlist += count; 583146950Sps return (error); 584146950Sps} 585146950Sps 586146950Sps/* 587146950Sps * Copy 'count' items from the list pointed to by uap->changelist. 588146950Sps */ 589146950Spsstatic int 590146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 591146950Sps{ 592146950Sps struct freebsd32_kevent_args *uap; 593146950Sps struct kevent32 ks32[KQ_NEVENTS]; 594146950Sps int i, error = 0; 595146950Sps 596146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 597146950Sps uap = (struct freebsd32_kevent_args *)arg; 598146950Sps 599146950Sps error = copyin(uap->changelist, ks32, count * sizeof *ks32); 600146950Sps if (error) 601146950Sps goto done; 602146950Sps uap->changelist += count; 603146950Sps 604146950Sps for (i = 0; i < count; i++) { 605146950Sps CP(ks32[i], kevp[i], ident); 606146950Sps CP(ks32[i], kevp[i], filter); 607146950Sps CP(ks32[i], kevp[i], flags); 608146950Sps CP(ks32[i], kevp[i], fflags); 609146950Sps CP(ks32[i], kevp[i], data); 610146950Sps PTRIN_CP(ks32[i], kevp[i], udata); 611146950Sps } 612146950Spsdone: 613146950Sps return (error); 614146950Sps} 615146950Sps 616100384Speterint 617119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 618114987Speter{ 619114987Speter struct timespec32 ts32; 620142934Sps struct timespec ts, *tsp; 621146950Sps struct kevent_copyops k_ops = { uap, 622146950Sps freebsd32_kevent_copyout, 623146950Sps freebsd32_kevent_copyin}; 624146950Sps int error; 625114987Speter 626114987Speter 627114987Speter if (uap->timeout) { 628114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 629114987Speter if (error) 630114987Speter return (error); 631114987Speter CP(ts32, ts, tv_sec); 632114987Speter CP(ts32, ts, tv_nsec); 633142934Sps tsp = &ts; 634142934Sps } else 635142934Sps tsp = NULL; 636146950Sps error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 637146950Sps &k_ops, tsp); 638142934Sps return (error); 639114987Speter} 640114987Speter 641114987Speterint 642119333Speterfreebsd32_gettimeofday(struct thread *td, 643119333Speter struct freebsd32_gettimeofday_args *uap) 644100384Speter{ 645123425Speter struct timeval atv; 646123425Speter struct timeval32 atv32; 647123425Speter struct timezone rtz; 648123425Speter int error = 0; 649100384Speter 650123425Speter if (uap->tp) { 651123425Speter microtime(&atv); 652123425Speter CP(atv, atv32, tv_sec); 653123425Speter CP(atv, atv32, tv_usec); 654123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 655100384Speter } 656123425Speter if (error == 0 && uap->tzp != NULL) { 657123425Speter rtz.tz_minuteswest = tz_minuteswest; 658123425Speter rtz.tz_dsttime = tz_dsttime; 659123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 660100384Speter } 661100384Speter return (error); 662100384Speter} 663100384Speter 664100384Speterint 665119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 666100384Speter{ 667136152Sjhb struct rusage32 s32; 668136152Sjhb struct rusage s; 669100384Speter int error; 670100384Speter 671136152Sjhb error = kern_getrusage(td, uap->who, &s); 672100384Speter if (error) 673100384Speter return (error); 674136152Sjhb if (uap->rusage != NULL) { 675100384Speter TV_CP(s, s32, ru_utime); 676100384Speter TV_CP(s, s32, ru_stime); 677100384Speter CP(s, s32, ru_maxrss); 678100384Speter CP(s, s32, ru_ixrss); 679100384Speter CP(s, s32, ru_idrss); 680100384Speter CP(s, s32, ru_isrss); 681100384Speter CP(s, s32, ru_minflt); 682100384Speter CP(s, s32, ru_majflt); 683100384Speter CP(s, s32, ru_nswap); 684100384Speter CP(s, s32, ru_inblock); 685100384Speter CP(s, s32, ru_oublock); 686100384Speter CP(s, s32, ru_msgsnd); 687100384Speter CP(s, s32, ru_msgrcv); 688100384Speter CP(s, s32, ru_nsignals); 689100384Speter CP(s, s32, ru_nvcsw); 690100384Speter CP(s, s32, ru_nivcsw); 691136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 692100384Speter } 693100384Speter return (error); 694100384Speter} 695100384Speter 696100384Speterstruct iovec32 { 697100384Speter u_int32_t iov_base; 698100384Speter int iov_len; 699100384Speter}; 700100384Speter 701121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 702121719Speter 703144450Sjhbstatic int 704144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 705100384Speter{ 706144450Sjhb struct iovec32 iov32; 707144450Sjhb struct iovec *iov; 708144450Sjhb struct uio *uio; 709144450Sjhb u_int iovlen; 710144450Sjhb int error, i; 711100384Speter 712144450Sjhb *uiop = NULL; 713144450Sjhb if (iovcnt > UIO_MAXIOV) 714100384Speter return (EINVAL); 715144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 716144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 717144450Sjhb iov = (struct iovec *)(uio + 1); 718144450Sjhb for (i = 0; i < iovcnt; i++) { 719144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 720144450Sjhb if (error) { 721144450Sjhb free(uio, M_IOV); 722144450Sjhb return (error); 723144450Sjhb } 724144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 725144450Sjhb iov[i].iov_len = iov32.iov_len; 726100384Speter } 727144450Sjhb uio->uio_iov = iov; 728144450Sjhb uio->uio_iovcnt = iovcnt; 729144450Sjhb uio->uio_segflg = UIO_USERSPACE; 730144450Sjhb uio->uio_offset = -1; 731144450Sjhb uio->uio_resid = 0; 732144450Sjhb for (i = 0; i < iovcnt; i++) { 733144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 734144450Sjhb free(uio, M_IOV); 735144450Sjhb return (EINVAL); 736144450Sjhb } 737144450Sjhb uio->uio_resid += iov->iov_len; 738144450Sjhb iov++; 739144450Sjhb } 740144450Sjhb *uiop = uio; 741144450Sjhb return (0); 742144450Sjhb} 743100384Speter 744144450Sjhbint 745144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 746144450Sjhb{ 747144450Sjhb struct uio *auio; 748144450Sjhb int error; 749100384Speter 750144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 751144450Sjhb if (error) 752144450Sjhb return (error); 753144450Sjhb error = kern_readv(td, uap->fd, auio); 754144450Sjhb free(auio, M_IOV); 755100384Speter return (error); 756100384Speter} 757100384Speter 758100384Speterint 759119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 760100384Speter{ 761144450Sjhb struct uio *auio; 762144450Sjhb int error; 763100384Speter 764144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 765144450Sjhb if (error) 766144450Sjhb return (error); 767144450Sjhb error = kern_writev(td, uap->fd, auio); 768144450Sjhb free(auio, M_IOV); 769100384Speter return (error); 770100384Speter} 771100384Speter 772100384Speterint 773147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 774147813Sjhb{ 775147813Sjhb struct uio *auio; 776147813Sjhb int error; 777147813Sjhb 778147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 779147813Sjhb if (error) 780147813Sjhb return (error); 781147813Sjhb error = kern_preadv(td, uap->fd, auio, uap->offset); 782147813Sjhb free(auio, M_IOV); 783147813Sjhb return (error); 784147813Sjhb} 785147813Sjhb 786147813Sjhbint 787147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 788147813Sjhb{ 789147813Sjhb struct uio *auio; 790147813Sjhb int error; 791147813Sjhb 792147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 793147813Sjhb if (error) 794147813Sjhb return (error); 795147813Sjhb error = kern_pwritev(td, uap->fd, auio, uap->offset); 796147813Sjhb free(auio, M_IOV); 797147813Sjhb return (error); 798147813Sjhb} 799147813Sjhb 800147813Sjhbint 801119333Speterfreebsd32_settimeofday(struct thread *td, 802119333Speter struct freebsd32_settimeofday_args *uap) 803100384Speter{ 804144450Sjhb struct timeval32 tv32; 805144450Sjhb struct timeval tv, *tvp; 806144450Sjhb struct timezone tz, *tzp; 807100384Speter int error; 808100384Speter 809144450Sjhb if (uap->tv) { 810144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 811100384Speter if (error) 812100384Speter return (error); 813144450Sjhb CP(tv32, tv, tv_sec); 814144450Sjhb CP(tv32, tv, tv_usec); 815144450Sjhb tvp = &tv; 816144450Sjhb } else 817144450Sjhb tvp = NULL; 818144450Sjhb if (uap->tzp) { 819144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 820100384Speter if (error) 821100384Speter return (error); 822144450Sjhb tzp = &tz; 823144450Sjhb } else 824144450Sjhb tzp = NULL; 825144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 826100384Speter} 827100384Speter 828100384Speterint 829119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 830100384Speter{ 831142059Sjhb struct timeval32 s32[2]; 832142059Sjhb struct timeval s[2], *sp; 833100384Speter int error; 834100384Speter 835142059Sjhb if (uap->tptr != NULL) { 836142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 837100384Speter if (error) 838100384Speter return (error); 839100384Speter CP(s32[0], s[0], tv_sec); 840100384Speter CP(s32[0], s[0], tv_usec); 841100384Speter CP(s32[1], s[1], tv_sec); 842100384Speter CP(s32[1], s[1], tv_usec); 843142059Sjhb sp = s; 844142059Sjhb } else 845142059Sjhb sp = NULL; 846142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 847100384Speter} 848100384Speter 849100384Speterint 850119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 851100384Speter{ 852144450Sjhb struct timeval32 tv32; 853144450Sjhb struct timeval delta, olddelta, *deltap; 854100384Speter int error; 855100384Speter 856144450Sjhb if (uap->delta) { 857144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 858100384Speter if (error) 859100384Speter return (error); 860144450Sjhb CP(tv32, delta, tv_sec); 861144450Sjhb CP(tv32, delta, tv_usec); 862144450Sjhb deltap = δ 863144450Sjhb } else 864144450Sjhb deltap = NULL; 865144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 866144450Sjhb if (uap->olddelta && error == 0) { 867144450Sjhb CP(olddelta, tv32, tv_sec); 868144450Sjhb CP(olddelta, tv32, tv_usec); 869144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 870100384Speter } 871100384Speter return (error); 872100384Speter} 873100384Speter 874128597Smarcel#ifdef COMPAT_FREEBSD4 875100384Speterint 876128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 877100384Speter{ 878142059Sjhb struct statfs32 s32; 879142059Sjhb struct statfs s; 880100384Speter int error; 881100384Speter 882142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 883100384Speter if (error) 884100384Speter return (error); 885142059Sjhb copy_statfs(&s, &s32); 886142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 887100384Speter} 888128597Smarcel#endif 889100384Speter 890128597Smarcel#ifdef COMPAT_FREEBSD4 891100384Speterint 892128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 893100384Speter{ 894142059Sjhb struct statfs32 s32; 895142059Sjhb struct statfs s; 896100384Speter int error; 897100384Speter 898142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 899100384Speter if (error) 900100384Speter return (error); 901142059Sjhb copy_statfs(&s, &s32); 902142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 903100384Speter} 904128597Smarcel#endif 905100384Speter 906128597Smarcel#ifdef COMPAT_FREEBSD4 907100384Speterint 908128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 909128260Speter{ 910142059Sjhb struct statfs32 s32; 911142059Sjhb struct statfs s; 912142059Sjhb fhandle_t fh; 913128260Speter int error; 914128260Speter 915142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 916142059Sjhb return (error); 917142059Sjhb error = kern_fhstatfs(td, fh, &s); 918128260Speter if (error) 919128260Speter return (error); 920142059Sjhb copy_statfs(&s, &s32); 921142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 922128260Speter} 923128597Smarcel#endif 924128260Speter 925128260Speterint 926119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 927100384Speter{ 928100384Speter /* 929100384Speter * Vector through to semsys if it is loaded. 930100384Speter */ 931150883Sjhb return sysent[SYS_semsys].sy_call(td, uap); 932100384Speter} 933100384Speter 934100384Speterint 935119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 936100384Speter{ 937100384Speter /* 938100384Speter * Vector through to msgsys if it is loaded. 939100384Speter */ 940150883Sjhb return sysent[SYS_msgsys].sy_call(td, uap); 941100384Speter} 942100384Speter 943100384Speterint 944119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 945100384Speter{ 946100384Speter /* 947100384Speter * Vector through to shmsys if it is loaded. 948100384Speter */ 949150883Sjhb return sysent[SYS_shmsys].sy_call(td, uap); 950100384Speter} 951100384Speter 952100384Speterint 953119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 954100384Speter{ 955100384Speter struct pread_args ap; 956100384Speter 957107849Salfred ap.fd = uap->fd; 958107849Salfred ap.buf = uap->buf; 959107849Salfred ap.nbyte = uap->nbyte; 960119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 961100384Speter return (pread(td, &ap)); 962100384Speter} 963100384Speter 964100384Speterint 965119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 966100384Speter{ 967100384Speter struct pwrite_args ap; 968100384Speter 969107849Salfred ap.fd = uap->fd; 970107849Salfred ap.buf = uap->buf; 971107849Salfred ap.nbyte = uap->nbyte; 972119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 973100384Speter return (pwrite(td, &ap)); 974100384Speter} 975100384Speter 976100384Speterint 977119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 978100384Speter{ 979100384Speter int error; 980100384Speter struct lseek_args ap; 981100384Speter off_t pos; 982100384Speter 983107849Salfred ap.fd = uap->fd; 984119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 985107849Salfred ap.whence = uap->whence; 986100384Speter error = lseek(td, &ap); 987100384Speter /* Expand the quad return into two parts for eax and edx */ 988100384Speter pos = *(off_t *)(td->td_retval); 989100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 990100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 991100384Speter return error; 992100384Speter} 993100384Speter 994100384Speterint 995119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 996100384Speter{ 997100384Speter struct truncate_args ap; 998100384Speter 999107849Salfred ap.path = uap->path; 1000119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1001100384Speter return (truncate(td, &ap)); 1002100384Speter} 1003100384Speter 1004100384Speterint 1005119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1006100384Speter{ 1007100384Speter struct ftruncate_args ap; 1008100384Speter 1009107849Salfred ap.fd = uap->fd; 1010119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1011100384Speter return (ftruncate(td, &ap)); 1012100384Speter} 1013100384Speter 1014104738Speter#ifdef COMPAT_FREEBSD4 1015100384Speterint 1016119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1017119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1018104738Speter{ 1019104738Speter struct freebsd4_sendfile_args ap; 1020104738Speter 1021107849Salfred ap.fd = uap->fd; 1022107849Salfred ap.s = uap->s; 1023119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1024107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1025107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1026107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1027107849Salfred ap.flags = uap->flags; 1028104738Speter return (freebsd4_sendfile(td, &ap)); 1029104738Speter} 1030104738Speter#endif 1031104738Speter 1032104738Speterint 1033119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1034100384Speter{ 1035100384Speter struct sendfile_args ap; 1036100384Speter 1037107849Salfred ap.fd = uap->fd; 1038107849Salfred ap.s = uap->s; 1039119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1040107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1041107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1042107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1043107849Salfred ap.flags = uap->flags; 1044100384Speter return (sendfile(td, &ap)); 1045100384Speter} 1046100384Speter 1047100384Speterstruct stat32 { 1048130640Sphk dev_t st_dev; 1049100384Speter ino_t st_ino; 1050100384Speter mode_t st_mode; 1051100384Speter nlink_t st_nlink; 1052100384Speter uid_t st_uid; 1053100384Speter gid_t st_gid; 1054130640Sphk dev_t st_rdev; 1055100384Speter struct timespec32 st_atimespec; 1056100384Speter struct timespec32 st_mtimespec; 1057100384Speter struct timespec32 st_ctimespec; 1058100384Speter off_t st_size; 1059100384Speter int64_t st_blocks; 1060100384Speter u_int32_t st_blksize; 1061100384Speter u_int32_t st_flags; 1062100384Speter u_int32_t st_gen; 1063121719Speter struct timespec32 st_birthtimespec; 1064121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1065121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1066100384Speter}; 1067100384Speter 1068121719Speter 1069121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1070121719Speter 1071100384Speterstatic void 1072100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1073100384Speter{ 1074100384Speter CP(*in, *out, st_dev); 1075100384Speter CP(*in, *out, st_ino); 1076100384Speter CP(*in, *out, st_mode); 1077100384Speter CP(*in, *out, st_nlink); 1078100384Speter CP(*in, *out, st_uid); 1079100384Speter CP(*in, *out, st_gid); 1080100384Speter CP(*in, *out, st_rdev); 1081100384Speter TS_CP(*in, *out, st_atimespec); 1082100384Speter TS_CP(*in, *out, st_mtimespec); 1083100384Speter TS_CP(*in, *out, st_ctimespec); 1084100384Speter CP(*in, *out, st_size); 1085100384Speter CP(*in, *out, st_blocks); 1086100384Speter CP(*in, *out, st_blksize); 1087100384Speter CP(*in, *out, st_flags); 1088100384Speter CP(*in, *out, st_gen); 1089100384Speter} 1090100384Speter 1091100384Speterint 1092119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1093100384Speter{ 1094123746Speter struct stat sb; 1095123746Speter struct stat32 sb32; 1096100384Speter int error; 1097100384Speter 1098142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1099100384Speter if (error) 1100100384Speter return (error); 1101123746Speter copy_stat(&sb, &sb32); 1102123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1103100384Speter return (error); 1104100384Speter} 1105100384Speter 1106100384Speterint 1107119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1108100384Speter{ 1109123746Speter struct stat ub; 1110123746Speter struct stat32 ub32; 1111100384Speter int error; 1112100384Speter 1113142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1114100384Speter if (error) 1115100384Speter return (error); 1116123746Speter copy_stat(&ub, &ub32); 1117123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1118100384Speter return (error); 1119100384Speter} 1120100384Speter 1121100384Speterint 1122119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1123100384Speter{ 1124123746Speter struct stat sb; 1125123746Speter struct stat32 sb32; 1126142059Sjhb int error; 1127100384Speter 1128142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1129100384Speter if (error) 1130100384Speter return (error); 1131123746Speter copy_stat(&sb, &sb32); 1132123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1133100384Speter return (error); 1134100384Speter} 1135100384Speter 1136100384Speter/* 1137100384Speter * MPSAFE 1138100384Speter */ 1139100384Speterint 1140119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1141100384Speter{ 1142100384Speter int error, name[CTL_MAXNAME]; 1143100384Speter size_t j, oldlen; 1144100384Speter 1145100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1146100384Speter return (EINVAL); 1147136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1148100384Speter if (error) 1149100384Speter return (error); 1150100384Speter mtx_lock(&Giant); 1151100384Speter if (uap->oldlenp) 1152100384Speter oldlen = fuword32(uap->oldlenp); 1153100384Speter else 1154100384Speter oldlen = 0; 1155100384Speter error = userland_sysctl(td, name, uap->namelen, 1156100384Speter uap->old, &oldlen, 1, 1157136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1158100384Speter if (error && error != ENOMEM) 1159100384Speter goto done2; 1160136404Speter if (uap->oldlenp) 1161100384Speter suword32(uap->oldlenp, j); 1162100384Speterdone2: 1163100384Speter mtx_unlock(&Giant); 1164100384Speter return (error); 1165100384Speter} 1166100384Speter 1167100384Speterstruct sigaction32 { 1168100384Speter u_int32_t sa_u; 1169100384Speter int sa_flags; 1170100384Speter sigset_t sa_mask; 1171100384Speter}; 1172100384Speter 1173121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1174121719Speter 1175100384Speterint 1176119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1177100384Speter{ 1178113859Sjhb struct sigaction32 s32; 1179113859Sjhb struct sigaction sa, osa, *sap; 1180100384Speter int error; 1181100384Speter 1182113859Sjhb if (uap->act) { 1183113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1184100384Speter if (error) 1185100384Speter return (error); 1186113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1187113859Sjhb CP(s32, sa, sa_flags); 1188113859Sjhb CP(s32, sa, sa_mask); 1189113859Sjhb sap = &sa; 1190113859Sjhb } else 1191113859Sjhb sap = NULL; 1192113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1193146583Sps if (error == 0 && uap->oact != NULL) { 1194113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1195113859Sjhb CP(osa, s32, sa_flags); 1196113859Sjhb CP(osa, s32, sa_mask); 1197113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1198100384Speter } 1199100384Speter return (error); 1200100384Speter} 1201100384Speter 1202114987Speter#ifdef COMPAT_FREEBSD4 1203114987Speterint 1204119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1205119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1206114987Speter{ 1207114987Speter struct sigaction32 s32; 1208114987Speter struct sigaction sa, osa, *sap; 1209114987Speter int error; 1210114987Speter 1211114987Speter if (uap->act) { 1212114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1213114987Speter if (error) 1214114987Speter return (error); 1215114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1216114987Speter CP(s32, sa, sa_flags); 1217114987Speter CP(s32, sa, sa_mask); 1218114987Speter sap = &sa; 1219114987Speter } else 1220114987Speter sap = NULL; 1221114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1222146583Sps if (error == 0 && uap->oact != NULL) { 1223114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1224114987Speter CP(osa, s32, sa_flags); 1225114987Speter CP(osa, s32, sa_mask); 1226114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1227114987Speter } 1228114987Speter return (error); 1229114987Speter} 1230114987Speter#endif 1231114987Speter 1232140481Spsint 1233140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1234140481Sps{ 1235140481Sps struct timespec32 rmt32, rqt32; 1236140481Sps struct timespec rmt, rqt; 1237140481Sps int error; 1238140481Sps 1239140481Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); 1240140481Sps if (error) 1241140481Sps return (error); 1242140481Sps 1243140481Sps CP(rqt32, rqt, tv_sec); 1244140481Sps CP(rqt32, rqt, tv_nsec); 1245140481Sps 1246140481Sps if (uap->rmtp && 1247140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1248140481Sps return (EFAULT); 1249140481Sps error = kern_nanosleep(td, &rqt, &rmt); 1250140481Sps if (error && uap->rmtp) { 1251140481Sps int error2; 1252140481Sps 1253140481Sps CP(rmt, rmt32, tv_sec); 1254140481Sps CP(rmt, rmt32, tv_nsec); 1255140481Sps 1256140481Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); 1257140481Sps if (error2) 1258140481Sps error = error2; 1259140481Sps } 1260140481Sps return (error); 1261140481Sps} 1262140481Sps 1263100384Speter#if 0 1264100384Speter 1265100384Speterint 1266119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1267100384Speter{ 1268100384Speter int error; 1269100384Speter struct yyy32 *p32, s32; 1270100384Speter struct yyy *p = NULL, s; 1271100384Speter 1272147654Sjhb if (uap->zzz) { 1273147654Sjhb error = copyin(uap->zzz, &s32, sizeof(s32)); 1274100384Speter if (error) 1275100384Speter return (error); 1276100384Speter /* translate in */ 1277147654Sjhb p = &s; 1278100384Speter } 1279147654Sjhb error = kern_xxx(td, p); 1280100384Speter if (error) 1281100384Speter return (error); 1282147654Sjhb if (uap->zzz) { 1283100384Speter /* translate out */ 1284100384Speter error = copyout(&s32, p32, sizeof(s32)); 1285100384Speter } 1286100384Speter return (error); 1287100384Speter} 1288100384Speter 1289100384Speter#endif 1290