freebsd32_misc.c revision 142059
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 142059 2005-02-18 18:56:04Z 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> 55100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 56100384Speter#include <sys/signal.h> 57100384Speter#include <sys/signalvar.h> 58100384Speter#include <sys/socket.h> 59100384Speter#include <sys/socketvar.h> 60100384Speter#include <sys/stat.h> 61113859Sjhb#include <sys/syscallsubr.h> 62100384Speter#include <sys/sysctl.h> 63100384Speter#include <sys/sysent.h> 64100384Speter#include <sys/sysproto.h> 65100384Speter#include <sys/systm.h> 66100384Speter#include <sys/unistd.h> 67100384Speter#include <sys/vnode.h> 68127140Sjhb#include <sys/wait.h> 69100384Speter 70100384Speter#include <vm/vm.h> 71100384Speter#include <vm/vm_kern.h> 72100384Speter#include <vm/vm_param.h> 73100384Speter#include <vm/pmap.h> 74100384Speter#include <vm/vm_map.h> 75100384Speter#include <vm/vm_object.h> 76100384Speter#include <vm/vm_extern.h> 77100384Speter 78119333Speter#include <compat/freebsd32/freebsd32_util.h> 79119333Speter#include <compat/freebsd32/freebsd32.h> 80119333Speter#include <compat/freebsd32/freebsd32_proto.h> 81100384Speter 82121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 83121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 84121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 85121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 86121719Speter 87100384Speterint 88119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 89100384Speter{ 90127140Sjhb int error, status; 91127140Sjhb struct rusage32 ru32; 92136152Sjhb struct rusage ru, *rup; 93100384Speter 94136152Sjhb if (uap->rusage != NULL) 95136152Sjhb rup = &ru; 96136152Sjhb else 97136152Sjhb rup = NULL; 98136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 99100384Speter if (error) 100100384Speter return (error); 101127140Sjhb if (uap->status != NULL) 102127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 103127140Sjhb if (uap->rusage != NULL && error == 0) { 104100384Speter TV_CP(ru, ru32, ru_utime); 105100384Speter TV_CP(ru, ru32, ru_stime); 106100384Speter CP(ru, ru32, ru_maxrss); 107100384Speter CP(ru, ru32, ru_ixrss); 108100384Speter CP(ru, ru32, ru_idrss); 109100384Speter CP(ru, ru32, ru_isrss); 110100384Speter CP(ru, ru32, ru_minflt); 111100384Speter CP(ru, ru32, ru_majflt); 112100384Speter CP(ru, ru32, ru_nswap); 113100384Speter CP(ru, ru32, ru_inblock); 114100384Speter CP(ru, ru32, ru_oublock); 115100384Speter CP(ru, ru32, ru_msgsnd); 116100384Speter CP(ru, ru32, ru_msgrcv); 117100384Speter CP(ru, ru32, ru_nsignals); 118100384Speter CP(ru, ru32, ru_nvcsw); 119100384Speter CP(ru, ru32, ru_nivcsw); 120127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 121100384Speter } 122100384Speter return (error); 123100384Speter} 124100384Speter 125128597Smarcel#ifdef COMPAT_FREEBSD4 126100384Speterstatic void 127100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 128100384Speter{ 129100384Speter CP(*in, *out, f_bsize); 130100384Speter CP(*in, *out, f_iosize); 131100384Speter CP(*in, *out, f_blocks); 132100384Speter CP(*in, *out, f_bfree); 133100384Speter CP(*in, *out, f_bavail); 134100384Speter CP(*in, *out, f_files); 135100384Speter CP(*in, *out, f_ffree); 136100384Speter CP(*in, *out, f_fsid); 137100384Speter CP(*in, *out, f_owner); 138100384Speter CP(*in, *out, f_type); 139100384Speter CP(*in, *out, f_flags); 140100384Speter CP(*in, *out, f_flags); 141100384Speter CP(*in, *out, f_syncwrites); 142100384Speter CP(*in, *out, f_asyncwrites); 143100384Speter bcopy(in->f_fstypename, 144100384Speter out->f_fstypename, MFSNAMELEN); 145100384Speter bcopy(in->f_mntonname, 146128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 147100384Speter CP(*in, *out, f_syncreads); 148100384Speter CP(*in, *out, f_asyncreads); 149100384Speter bcopy(in->f_mntfromname, 150128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 151100384Speter} 152128597Smarcel#endif 153100384Speter 154128597Smarcel#ifdef COMPAT_FREEBSD4 155100384Speterint 156128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 157100384Speter{ 158100384Speter int error; 159100384Speter caddr_t sg; 160100384Speter struct statfs32 *sp32, stat32; 161100384Speter struct statfs *sp = NULL, stat; 162100384Speter int maxcount, count, i; 163100384Speter 164107849Salfred sp32 = uap->buf; 165107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 166100384Speter 167100384Speter if (sp32) { 168100384Speter sg = stackgap_init(); 169100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 170107849Salfred uap->buf = (struct statfs32 *)sp; 171100384Speter } 172100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 173100384Speter if (sp32 && !error) { 174100384Speter count = td->td_retval[0]; 175100384Speter for (i = 0; i < count; i++) { 176100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 177100384Speter if (error) 178100384Speter return (error); 179100384Speter copy_statfs(&stat, &stat32); 180100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 181100384Speter if (error) 182100384Speter return (error); 183100384Speter } 184100384Speter } 185100384Speter return (error); 186100384Speter} 187128597Smarcel#endif 188100384Speter 189100384Speterstruct sigaltstack32 { 190100384Speter u_int32_t ss_sp; 191100384Speter u_int32_t ss_size; 192100384Speter int ss_flags; 193100384Speter}; 194100384Speter 195121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 196121719Speter 197100384Speterint 198119333Speterfreebsd32_sigaltstack(struct thread *td, 199119333Speter struct freebsd32_sigaltstack_args *uap) 200100384Speter{ 201113859Sjhb struct sigaltstack32 s32; 202113859Sjhb struct sigaltstack ss, oss, *ssp; 203100384Speter int error; 204100384Speter 205113859Sjhb if (uap->ss != NULL) { 206113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 207100384Speter if (error) 208100384Speter return (error); 209113859Sjhb PTRIN_CP(s32, ss, ss_sp); 210113859Sjhb CP(s32, ss, ss_size); 211113859Sjhb CP(s32, ss, ss_flags); 212113859Sjhb ssp = &ss; 213113859Sjhb } else 214113859Sjhb ssp = NULL; 215113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 216113859Sjhb if (error == 0 && uap->oss != NULL) { 217113859Sjhb PTROUT_CP(oss, s32, ss_sp); 218113859Sjhb CP(oss, s32, ss_size); 219113859Sjhb CP(oss, s32, ss_flags); 220113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 221100384Speter } 222100384Speter return (error); 223100384Speter} 224100384Speter 225142059Sjhb/* 226142059Sjhb * Custom version of exec_copyin_args() so that we can translate 227142059Sjhb * the pointers. 228142059Sjhb */ 229142059Sjhbstatic int 230142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 231142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 232100384Speter{ 233142059Sjhb char *argp, *envp; 234142059Sjhb u_int32_t *p32, arg; 235142059Sjhb size_t length; 236100384Speter int error; 237100384Speter 238142059Sjhb bzero(args, sizeof(*args)); 239142059Sjhb if (argv == NULL) 240142059Sjhb return (EFAULT); 241100384Speter 242142059Sjhb /* 243142059Sjhb * Allocate temporary demand zeroed space for argument and 244142059Sjhb * environment strings 245142059Sjhb */ 246142059Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX); 247142059Sjhb if (args->buf == NULL) 248142059Sjhb return (ENOMEM); 249142059Sjhb args->begin_argv = args->buf; 250142059Sjhb args->endp = args->begin_argv; 251142059Sjhb args->stringspace = ARG_MAX; 252142059Sjhb 253142059Sjhb args->fname = args->buf + ARG_MAX; 254142059Sjhb 255142059Sjhb /* 256142059Sjhb * Copy the file name. 257142059Sjhb */ 258142059Sjhb error = (segflg == UIO_SYSSPACE) ? 259142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 260142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 261142059Sjhb if (error != 0) 262142059Sjhb return (error); 263142059Sjhb 264142059Sjhb /* 265142059Sjhb * extract arguments first 266142059Sjhb */ 267142059Sjhb p32 = argv; 268142059Sjhb for (;;) { 269142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 270142059Sjhb if (error) 271142059Sjhb return (error); 272142059Sjhb if (arg == 0) 273142059Sjhb break; 274142059Sjhb argp = PTRIN(arg); 275142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 276142059Sjhb if (error) { 277142059Sjhb if (error == ENAMETOOLONG) 278142059Sjhb return (E2BIG); 279142059Sjhb else 280142059Sjhb return (error); 281142059Sjhb } 282142059Sjhb args->stringspace -= length; 283142059Sjhb args->endp += length; 284142059Sjhb args->argc++; 285100384Speter } 286142059Sjhb 287142059Sjhb args->begin_envv = args->endp; 288142059Sjhb 289142059Sjhb /* 290142059Sjhb * extract environment strings 291142059Sjhb */ 292142059Sjhb if (envv) { 293142059Sjhb p32 = envv; 294142059Sjhb for (;;) { 295100384Speter error = copyin(p32++, &arg, sizeof(arg)); 296100384Speter if (error) 297142059Sjhb return (error); 298142059Sjhb if (arg == 0) 299142059Sjhb break; 300142059Sjhb envp = PTRIN(arg); 301142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 302142059Sjhb &length); 303142059Sjhb if (error) { 304142059Sjhb if (error == ENAMETOOLONG) 305142059Sjhb return (E2BIG); 306142059Sjhb else 307142059Sjhb return (error); 308142059Sjhb } 309142059Sjhb args->stringspace -= length; 310142059Sjhb args->endp += length; 311142059Sjhb args->envc++; 312142059Sjhb } 313100384Speter } 314100384Speter 315142059Sjhb return (0); 316100384Speter} 317100384Speter 318142059Sjhbint 319142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 320142059Sjhb{ 321142059Sjhb struct image_args eargs; 322142059Sjhb int error; 323142059Sjhb 324142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 325142059Sjhb uap->argv, uap->envv); 326142059Sjhb if (error == 0) 327142059Sjhb error = kern_execve(td, &eargs, NULL); 328142059Sjhb exec_free_args(&eargs); 329142059Sjhb return (error); 330142059Sjhb} 331142059Sjhb 332114987Speter#ifdef __ia64__ 333100384Speterstatic int 334119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 335119333Speter int prot, int fd, off_t pos) 336100384Speter{ 337100384Speter vm_map_t map; 338100384Speter vm_map_entry_t entry; 339100384Speter int rv; 340100384Speter 341100384Speter map = &td->td_proc->p_vmspace->vm_map; 342100384Speter if (fd != -1) 343100384Speter prot |= VM_PROT_WRITE; 344100384Speter 345100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 346100384Speter if ((entry->protection & prot) != prot) { 347100384Speter rv = vm_map_protect(map, 348100384Speter trunc_page(start), 349100384Speter round_page(end), 350100384Speter entry->protection | prot, 351100384Speter FALSE); 352100384Speter if (rv != KERN_SUCCESS) 353100384Speter return (EINVAL); 354100384Speter } 355100384Speter } else { 356100384Speter vm_offset_t addr = trunc_page(start); 357100384Speter rv = vm_map_find(map, 0, 0, 358100384Speter &addr, PAGE_SIZE, FALSE, prot, 359100384Speter VM_PROT_ALL, 0); 360100384Speter if (rv != KERN_SUCCESS) 361100384Speter return (EINVAL); 362100384Speter } 363100384Speter 364100384Speter if (fd != -1) { 365100384Speter struct pread_args r; 366107849Salfred r.fd = fd; 367107849Salfred r.buf = (void *) start; 368107849Salfred r.nbyte = end - start; 369107849Salfred r.offset = pos; 370100384Speter return (pread(td, &r)); 371100384Speter } else { 372100384Speter while (start < end) { 373100384Speter subyte((void *) start, 0); 374100384Speter start++; 375100384Speter } 376100384Speter return (0); 377100384Speter } 378100384Speter} 379114987Speter#endif 380100384Speter 381100384Speterint 382119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 383100384Speter{ 384100384Speter struct mmap_args ap; 385107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 386107849Salfred vm_size_t len = uap->len; 387107849Salfred int prot = uap->prot; 388107849Salfred int flags = uap->flags; 389107849Salfred int fd = uap->fd; 390107849Salfred off_t pos = (uap->poslo 391107849Salfred | ((off_t)uap->poshi << 32)); 392114987Speter#ifdef __ia64__ 393100384Speter vm_size_t pageoff; 394100384Speter int error; 395100384Speter 396100384Speter /* 397100384Speter * Attempt to handle page size hassles. 398100384Speter */ 399100384Speter pageoff = (pos & PAGE_MASK); 400100384Speter if (flags & MAP_FIXED) { 401100384Speter vm_offset_t start, end; 402100384Speter start = addr; 403100384Speter end = addr + len; 404100384Speter 405100384Speter if (start != trunc_page(start)) { 406119333Speter error = freebsd32_mmap_partial(td, start, 407119333Speter round_page(start), prot, 408119333Speter fd, pos); 409100384Speter if (fd != -1) 410100384Speter pos += round_page(start) - start; 411100384Speter start = round_page(start); 412100384Speter } 413100384Speter if (end != round_page(end)) { 414100384Speter vm_offset_t t = trunc_page(end); 415119333Speter error = freebsd32_mmap_partial(td, t, end, 416100384Speter prot, fd, 417100384Speter pos + t - start); 418100384Speter end = trunc_page(end); 419100384Speter } 420100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 421100384Speter /* 422100384Speter * We can't map this region at all. The specified 423100384Speter * address doesn't have the same alignment as the file 424100384Speter * position. Fake the mapping by simply reading the 425100384Speter * entire region into memory. First we need to make 426100384Speter * sure the region exists. 427100384Speter */ 428100384Speter vm_map_t map; 429100384Speter struct pread_args r; 430100384Speter int rv; 431100384Speter 432100384Speter prot |= VM_PROT_WRITE; 433100384Speter map = &td->td_proc->p_vmspace->vm_map; 434100384Speter rv = vm_map_remove(map, start, end); 435100384Speter if (rv != KERN_SUCCESS) 436100384Speter return (EINVAL); 437100384Speter rv = vm_map_find(map, 0, 0, 438100384Speter &start, end - start, FALSE, 439100384Speter prot, VM_PROT_ALL, 0); 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 } 453100384Speter if (end == start) { 454100384Speter /* 455100384Speter * After dealing with the ragged ends, there 456100384Speter * might be none left. 457100384Speter */ 458100384Speter td->td_retval[0] = addr; 459100384Speter return (0); 460100384Speter } 461100384Speter addr = start; 462100384Speter len = end - start; 463100384Speter } 464114987Speter#endif 465100384Speter 466107849Salfred ap.addr = (void *) addr; 467107849Salfred ap.len = len; 468107849Salfred ap.prot = prot; 469107849Salfred ap.flags = flags; 470107849Salfred ap.fd = fd; 471107849Salfred ap.pos = pos; 472100384Speter 473100384Speter return (mmap(td, &ap)); 474100384Speter} 475100384Speter 476100384Speterstruct itimerval32 { 477100384Speter struct timeval32 it_interval; 478100384Speter struct timeval32 it_value; 479100384Speter}; 480100384Speter 481121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 482121719Speter 483100384Speterint 484119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 485100384Speter{ 486142059Sjhb struct itimerval itv, oitv, *itvp; 487142059Sjhb struct itimerval32 i32; 488100384Speter int error; 489100384Speter 490142059Sjhb if (uap->itv != NULL) { 491142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 492100384Speter if (error) 493100384Speter return (error); 494142059Sjhb TV_CP(i32, itv, it_interval); 495142059Sjhb TV_CP(i32, itv, it_value); 496142059Sjhb itvp = &itv; 497142059Sjhb } else 498142059Sjhb itvp = NULL; 499142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 500142059Sjhb if (error || uap->oitv == NULL) 501100384Speter return (error); 502142059Sjhb TV_CP(oitv, i32, it_interval); 503142059Sjhb TV_CP(oitv, i32, it_value); 504142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 505100384Speter} 506100384Speter 507100384Speterint 508125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 509125171Speter{ 510142059Sjhb struct itimerval itv; 511142059Sjhb struct itimerval32 i32; 512125171Speter int error; 513125171Speter 514142059Sjhb error = kern_getitimer(td, uap->which, &itv); 515142059Sjhb if (error || uap->itv == NULL) 516125171Speter return (error); 517142059Sjhb TV_CP(itv, i32, it_interval); 518142059Sjhb TV_CP(itv, i32, it_value); 519142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 520125171Speter} 521125171Speter 522125171Speterint 523119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 524100384Speter{ 525142059Sjhb struct timeval32 tv32; 526142059Sjhb struct timeval tv, *tvp; 527100384Speter int error; 528100384Speter 529142059Sjhb if (uap->tv != NULL) { 530142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 531100384Speter if (error) 532100384Speter return (error); 533142059Sjhb CP(tv32, tv, tv_sec); 534142059Sjhb CP(tv32, tv, tv_usec); 535142059Sjhb tvp = &tv; 536142059Sjhb } else 537142059Sjhb tvp = NULL; 538100384Speter /* 539100384Speter * XXX big-endian needs to convert the fd_sets too. 540142059Sjhb * XXX Do pointers need PTRIN()? 541100384Speter */ 542142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 543100384Speter} 544100384Speter 545114987Speterstruct kevent32 { 546114987Speter u_int32_t ident; /* identifier for this event */ 547114987Speter short filter; /* filter for event */ 548114987Speter u_short flags; 549114987Speter u_int fflags; 550114987Speter int32_t data; 551114987Speter u_int32_t udata; /* opaque user data identifier */ 552114987Speter}; 553114987Speter 554121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 555121719Speter 556100384Speterint 557119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 558114987Speter{ 559114987Speter int error; 560114987Speter caddr_t sg; 561114987Speter struct timespec32 ts32; 562114987Speter struct timespec ts; 563114987Speter struct kevent32 ks32; 564114987Speter struct kevent *ks; 565114987Speter struct kevent_args a; 566114987Speter int i; 567114987Speter 568114987Speter sg = stackgap_init(); 569114987Speter 570114987Speter a.fd = uap->fd; 571114987Speter a.changelist = uap->changelist; 572114987Speter a.nchanges = uap->nchanges; 573114987Speter a.eventlist = uap->eventlist; 574114987Speter a.nevents = uap->nevents; 575114987Speter a.timeout = NULL; 576114987Speter 577114987Speter if (uap->timeout) { 578114987Speter a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 579114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 580114987Speter if (error) 581114987Speter return (error); 582114987Speter CP(ts32, ts, tv_sec); 583114987Speter CP(ts32, ts, tv_nsec); 584114987Speter error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 585114987Speter if (error) 586114987Speter return (error); 587114987Speter } 588114987Speter if (uap->changelist) { 589119333Speter a.changelist = (struct kevent *)stackgap_alloc(&sg, 590119333Speter uap->nchanges * sizeof(struct kevent)); 591114987Speter for (i = 0; i < uap->nchanges; i++) { 592119333Speter error = copyin(&uap->changelist[i], &ks32, 593119333Speter sizeof(ks32)); 594114987Speter if (error) 595114987Speter return (error); 596114987Speter ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 597114987Speter CP(ks32, *ks, ident); 598114987Speter CP(ks32, *ks, filter); 599114987Speter CP(ks32, *ks, flags); 600114987Speter CP(ks32, *ks, fflags); 601114987Speter CP(ks32, *ks, data); 602114987Speter PTRIN_CP(ks32, *ks, udata); 603114987Speter } 604114987Speter } 605114987Speter if (uap->eventlist) { 606119333Speter a.eventlist = stackgap_alloc(&sg, 607119333Speter uap->nevents * sizeof(struct kevent)); 608114987Speter } 609114987Speter error = kevent(td, &a); 610114987Speter if (uap->eventlist && error > 0) { 611114987Speter for (i = 0; i < error; i++) { 612114987Speter ks = &a.eventlist[i]; 613114987Speter CP(*ks, ks32, ident); 614114987Speter CP(*ks, ks32, filter); 615114987Speter CP(*ks, ks32, flags); 616114987Speter CP(*ks, ks32, fflags); 617114987Speter CP(*ks, ks32, data); 618114987Speter PTROUT_CP(*ks, ks32, udata); 619119333Speter error = copyout(&ks32, &uap->eventlist[i], 620119333Speter sizeof(ks32)); 621114987Speter if (error) 622114987Speter return (error); 623114987Speter } 624114987Speter } 625114987Speter return error; 626114987Speter} 627114987Speter 628114987Speterint 629119333Speterfreebsd32_gettimeofday(struct thread *td, 630119333Speter struct freebsd32_gettimeofday_args *uap) 631100384Speter{ 632123425Speter struct timeval atv; 633123425Speter struct timeval32 atv32; 634123425Speter struct timezone rtz; 635123425Speter int error = 0; 636100384Speter 637123425Speter if (uap->tp) { 638123425Speter microtime(&atv); 639123425Speter CP(atv, atv32, tv_sec); 640123425Speter CP(atv, atv32, tv_usec); 641123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 642100384Speter } 643123425Speter if (error == 0 && uap->tzp != NULL) { 644123425Speter rtz.tz_minuteswest = tz_minuteswest; 645123425Speter rtz.tz_dsttime = tz_dsttime; 646123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 647100384Speter } 648100384Speter return (error); 649100384Speter} 650100384Speter 651100384Speterint 652119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 653100384Speter{ 654136152Sjhb struct rusage32 s32; 655136152Sjhb struct rusage s; 656100384Speter int error; 657100384Speter 658136152Sjhb error = kern_getrusage(td, uap->who, &s); 659100384Speter if (error) 660100384Speter return (error); 661136152Sjhb if (uap->rusage != NULL) { 662100384Speter TV_CP(s, s32, ru_utime); 663100384Speter TV_CP(s, s32, ru_stime); 664100384Speter CP(s, s32, ru_maxrss); 665100384Speter CP(s, s32, ru_ixrss); 666100384Speter CP(s, s32, ru_idrss); 667100384Speter CP(s, s32, ru_isrss); 668100384Speter CP(s, s32, ru_minflt); 669100384Speter CP(s, s32, ru_majflt); 670100384Speter CP(s, s32, ru_nswap); 671100384Speter CP(s, s32, ru_inblock); 672100384Speter CP(s, s32, ru_oublock); 673100384Speter CP(s, s32, ru_msgsnd); 674100384Speter CP(s, s32, ru_msgrcv); 675100384Speter CP(s, s32, ru_nsignals); 676100384Speter CP(s, s32, ru_nvcsw); 677100384Speter CP(s, s32, ru_nivcsw); 678136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 679100384Speter } 680100384Speter return (error); 681100384Speter} 682100384Speter 683100384Speterstruct iovec32 { 684100384Speter u_int32_t iov_base; 685100384Speter int iov_len; 686100384Speter}; 687100384Speter#define STACKGAPLEN 400 688100384Speter 689121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 690121719Speter 691100384Speterint 692119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 693100384Speter{ 694100384Speter int error, osize, nsize, i; 695100384Speter caddr_t sg; 696100384Speter struct readv_args /* { 697100384Speter syscallarg(int) fd; 698100384Speter syscallarg(struct iovec *) iovp; 699100384Speter syscallarg(u_int) iovcnt; 700100384Speter } */ a; 701100384Speter struct iovec32 *oio; 702100384Speter struct iovec *nio; 703100384Speter 704100384Speter sg = stackgap_init(); 705100384Speter 706107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 707100384Speter return (EINVAL); 708100384Speter 709107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 710107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 711100384Speter 712111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 713111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 714100384Speter 715100384Speter error = 0; 716107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 717100384Speter goto punt; 718107849Salfred for (i = 0; i < uap->iovcnt; i++) { 719100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 720100384Speter nio[i].iov_len = oio[i].iov_len; 721100384Speter } 722100384Speter 723107849Salfred a.fd = uap->fd; 724107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 725107849Salfred a.iovcnt = uap->iovcnt; 726100384Speter 727107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 728100384Speter goto punt; 729100384Speter error = readv(td, &a); 730100384Speter 731100384Speterpunt: 732100384Speter free(oio, M_TEMP); 733100384Speter free(nio, M_TEMP); 734100384Speter return (error); 735100384Speter} 736100384Speter 737100384Speterint 738119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 739100384Speter{ 740100384Speter int error, i, nsize, osize; 741100384Speter caddr_t sg; 742100384Speter struct writev_args /* { 743100384Speter syscallarg(int) fd; 744100384Speter syscallarg(struct iovec *) iovp; 745100384Speter syscallarg(u_int) iovcnt; 746100384Speter } */ a; 747100384Speter struct iovec32 *oio; 748100384Speter struct iovec *nio; 749100384Speter 750100384Speter sg = stackgap_init(); 751100384Speter 752107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 753100384Speter return (EINVAL); 754100384Speter 755107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 756107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 757100384Speter 758111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 759111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 760100384Speter 761100384Speter error = 0; 762107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 763100384Speter goto punt; 764107849Salfred for (i = 0; i < uap->iovcnt; i++) { 765100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 766100384Speter nio[i].iov_len = oio[i].iov_len; 767100384Speter } 768100384Speter 769107849Salfred a.fd = uap->fd; 770107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 771107849Salfred a.iovcnt = uap->iovcnt; 772100384Speter 773107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 774100384Speter goto punt; 775100384Speter error = writev(td, &a); 776100384Speter 777100384Speterpunt: 778100384Speter free(oio, M_TEMP); 779100384Speter free(nio, M_TEMP); 780100384Speter return (error); 781100384Speter} 782100384Speter 783100384Speterint 784119333Speterfreebsd32_settimeofday(struct thread *td, 785119333Speter struct freebsd32_settimeofday_args *uap) 786100384Speter{ 787100384Speter int error; 788100384Speter caddr_t sg; 789100384Speter struct timeval32 *p32, s32; 790100384Speter struct timeval *p = NULL, s; 791100384Speter 792107849Salfred p32 = uap->tv; 793100384Speter if (p32) { 794100384Speter sg = stackgap_init(); 795100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 796107849Salfred uap->tv = (struct timeval32 *)p; 797100384Speter error = copyin(p32, &s32, sizeof(s32)); 798100384Speter if (error) 799100384Speter return (error); 800100384Speter CP(s32, s, tv_sec); 801100384Speter CP(s32, s, tv_usec); 802100384Speter error = copyout(&s, p, sizeof(s)); 803100384Speter if (error) 804100384Speter return (error); 805100384Speter } 806100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 807100384Speter} 808100384Speter 809100384Speterint 810119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 811100384Speter{ 812142059Sjhb struct timeval32 s32[2]; 813142059Sjhb struct timeval s[2], *sp; 814100384Speter int error; 815100384Speter 816142059Sjhb if (uap->tptr != NULL) { 817142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 818100384Speter if (error) 819100384Speter return (error); 820100384Speter CP(s32[0], s[0], tv_sec); 821100384Speter CP(s32[0], s[0], tv_usec); 822100384Speter CP(s32[1], s[1], tv_sec); 823100384Speter CP(s32[1], s[1], tv_usec); 824142059Sjhb sp = s; 825142059Sjhb } else 826142059Sjhb sp = NULL; 827142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 828100384Speter} 829100384Speter 830100384Speterint 831119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 832100384Speter{ 833100384Speter int error; 834100384Speter caddr_t sg; 835100384Speter struct timeval32 *p32, *op32, s32; 836100384Speter struct timeval *p = NULL, *op = NULL, s; 837100384Speter 838107849Salfred p32 = uap->delta; 839100384Speter if (p32) { 840100384Speter sg = stackgap_init(); 841100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 842107849Salfred uap->delta = (struct timeval32 *)p; 843100384Speter error = copyin(p32, &s32, sizeof(s32)); 844100384Speter if (error) 845100384Speter return (error); 846100384Speter CP(s32, s, tv_sec); 847100384Speter CP(s32, s, tv_usec); 848100384Speter error = copyout(&s, p, sizeof(s)); 849100384Speter if (error) 850100384Speter return (error); 851100384Speter } 852107849Salfred op32 = uap->olddelta; 853100384Speter if (op32) { 854100384Speter sg = stackgap_init(); 855100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 856107849Salfred uap->olddelta = (struct timeval32 *)op; 857100384Speter } 858142059Sjhb error = adjtime(td, (struct adjtime_args *) uap); 859100384Speter if (error) 860100384Speter return error; 861100384Speter if (op32) { 862100384Speter error = copyin(op, &s, sizeof(s)); 863100384Speter if (error) 864100384Speter return (error); 865100384Speter CP(s, s32, tv_sec); 866100384Speter CP(s, s32, tv_usec); 867100384Speter error = copyout(&s32, op32, sizeof(s32)); 868100384Speter } 869100384Speter return (error); 870100384Speter} 871100384Speter 872128597Smarcel#ifdef COMPAT_FREEBSD4 873100384Speterint 874128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 875100384Speter{ 876142059Sjhb struct statfs32 s32; 877142059Sjhb struct statfs s; 878100384Speter int error; 879100384Speter 880142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 881100384Speter if (error) 882100384Speter return (error); 883142059Sjhb copy_statfs(&s, &s32); 884142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 885100384Speter} 886128597Smarcel#endif 887100384Speter 888128597Smarcel#ifdef COMPAT_FREEBSD4 889100384Speterint 890128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 891100384Speter{ 892142059Sjhb struct statfs32 s32; 893142059Sjhb struct statfs s; 894100384Speter int error; 895100384Speter 896142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 897100384Speter if (error) 898100384Speter return (error); 899142059Sjhb copy_statfs(&s, &s32); 900142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 901100384Speter} 902128597Smarcel#endif 903100384Speter 904128597Smarcel#ifdef COMPAT_FREEBSD4 905100384Speterint 906128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 907128260Speter{ 908142059Sjhb struct statfs32 s32; 909142059Sjhb struct statfs s; 910142059Sjhb fhandle_t fh; 911128260Speter int error; 912128260Speter 913142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 914142059Sjhb return (error); 915142059Sjhb error = kern_fhstatfs(td, fh, &s); 916128260Speter if (error) 917128260Speter return (error); 918142059Sjhb copy_statfs(&s, &s32); 919142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 920128260Speter} 921128597Smarcel#endif 922128260Speter 923128260Speterint 924119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 925100384Speter{ 926100384Speter /* 927100384Speter * Vector through to semsys if it is loaded. 928100384Speter */ 929100384Speter return sysent[169].sy_call(td, uap); 930100384Speter} 931100384Speter 932100384Speterint 933119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 934100384Speter{ 935100384Speter /* 936100384Speter * Vector through to msgsys if it is loaded. 937100384Speter */ 938100384Speter return sysent[170].sy_call(td, uap); 939100384Speter} 940100384Speter 941100384Speterint 942119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 943100384Speter{ 944100384Speter /* 945100384Speter * Vector through to shmsys if it is loaded. 946100384Speter */ 947100384Speter return sysent[171].sy_call(td, uap); 948100384Speter} 949100384Speter 950100384Speterint 951119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 952100384Speter{ 953100384Speter struct pread_args ap; 954100384Speter 955107849Salfred ap.fd = uap->fd; 956107849Salfred ap.buf = uap->buf; 957107849Salfred ap.nbyte = uap->nbyte; 958119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 959100384Speter return (pread(td, &ap)); 960100384Speter} 961100384Speter 962100384Speterint 963119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 964100384Speter{ 965100384Speter struct pwrite_args ap; 966100384Speter 967107849Salfred ap.fd = uap->fd; 968107849Salfred ap.buf = uap->buf; 969107849Salfred ap.nbyte = uap->nbyte; 970119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 971100384Speter return (pwrite(td, &ap)); 972100384Speter} 973100384Speter 974100384Speterint 975119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 976100384Speter{ 977100384Speter int error; 978100384Speter struct lseek_args ap; 979100384Speter off_t pos; 980100384Speter 981107849Salfred ap.fd = uap->fd; 982119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 983107849Salfred ap.whence = uap->whence; 984100384Speter error = lseek(td, &ap); 985100384Speter /* Expand the quad return into two parts for eax and edx */ 986100384Speter pos = *(off_t *)(td->td_retval); 987100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 988100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 989100384Speter return error; 990100384Speter} 991100384Speter 992100384Speterint 993119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 994100384Speter{ 995100384Speter struct truncate_args ap; 996100384Speter 997107849Salfred ap.path = uap->path; 998119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 999100384Speter return (truncate(td, &ap)); 1000100384Speter} 1001100384Speter 1002100384Speterint 1003119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1004100384Speter{ 1005100384Speter struct ftruncate_args ap; 1006100384Speter 1007107849Salfred ap.fd = uap->fd; 1008119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1009100384Speter return (ftruncate(td, &ap)); 1010100384Speter} 1011100384Speter 1012104738Speter#ifdef COMPAT_FREEBSD4 1013100384Speterint 1014119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1015119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1016104738Speter{ 1017104738Speter struct freebsd4_sendfile_args ap; 1018104738Speter 1019107849Salfred ap.fd = uap->fd; 1020107849Salfred ap.s = uap->s; 1021119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1022107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1023107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1024107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1025107849Salfred ap.flags = uap->flags; 1026104738Speter return (freebsd4_sendfile(td, &ap)); 1027104738Speter} 1028104738Speter#endif 1029104738Speter 1030104738Speterint 1031119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1032100384Speter{ 1033100384Speter struct sendfile_args ap; 1034100384Speter 1035107849Salfred ap.fd = uap->fd; 1036107849Salfred ap.s = uap->s; 1037119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1038107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1039107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1040107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1041107849Salfred ap.flags = uap->flags; 1042100384Speter return (sendfile(td, &ap)); 1043100384Speter} 1044100384Speter 1045100384Speterstruct stat32 { 1046130640Sphk dev_t st_dev; 1047100384Speter ino_t st_ino; 1048100384Speter mode_t st_mode; 1049100384Speter nlink_t st_nlink; 1050100384Speter uid_t st_uid; 1051100384Speter gid_t st_gid; 1052130640Sphk dev_t st_rdev; 1053100384Speter struct timespec32 st_atimespec; 1054100384Speter struct timespec32 st_mtimespec; 1055100384Speter struct timespec32 st_ctimespec; 1056100384Speter off_t st_size; 1057100384Speter int64_t st_blocks; 1058100384Speter u_int32_t st_blksize; 1059100384Speter u_int32_t st_flags; 1060100384Speter u_int32_t st_gen; 1061121719Speter struct timespec32 st_birthtimespec; 1062121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1063121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1064100384Speter}; 1065100384Speter 1066121719Speter 1067121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1068121719Speter 1069100384Speterstatic void 1070100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1071100384Speter{ 1072100384Speter CP(*in, *out, st_dev); 1073100384Speter CP(*in, *out, st_ino); 1074100384Speter CP(*in, *out, st_mode); 1075100384Speter CP(*in, *out, st_nlink); 1076100384Speter CP(*in, *out, st_uid); 1077100384Speter CP(*in, *out, st_gid); 1078100384Speter CP(*in, *out, st_rdev); 1079100384Speter TS_CP(*in, *out, st_atimespec); 1080100384Speter TS_CP(*in, *out, st_mtimespec); 1081100384Speter TS_CP(*in, *out, st_ctimespec); 1082100384Speter CP(*in, *out, st_size); 1083100384Speter CP(*in, *out, st_blocks); 1084100384Speter CP(*in, *out, st_blksize); 1085100384Speter CP(*in, *out, st_flags); 1086100384Speter CP(*in, *out, st_gen); 1087100384Speter} 1088100384Speter 1089100384Speterint 1090119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1091100384Speter{ 1092123746Speter struct stat sb; 1093123746Speter struct stat32 sb32; 1094100384Speter int error; 1095100384Speter 1096142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1097100384Speter if (error) 1098100384Speter return (error); 1099123746Speter copy_stat(&sb, &sb32); 1100123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1101100384Speter return (error); 1102100384Speter} 1103100384Speter 1104100384Speterint 1105119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1106100384Speter{ 1107123746Speter struct stat ub; 1108123746Speter struct stat32 ub32; 1109100384Speter int error; 1110100384Speter 1111142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1112100384Speter if (error) 1113100384Speter return (error); 1114123746Speter copy_stat(&ub, &ub32); 1115123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1116100384Speter return (error); 1117100384Speter} 1118100384Speter 1119100384Speterint 1120119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1121100384Speter{ 1122123746Speter struct stat sb; 1123123746Speter struct stat32 sb32; 1124142059Sjhb int error; 1125100384Speter 1126142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1127100384Speter if (error) 1128100384Speter return (error); 1129123746Speter copy_stat(&sb, &sb32); 1130123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1131100384Speter return (error); 1132100384Speter} 1133100384Speter 1134100384Speter/* 1135100384Speter * MPSAFE 1136100384Speter */ 1137100384Speterint 1138119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1139100384Speter{ 1140100384Speter int error, name[CTL_MAXNAME]; 1141100384Speter size_t j, oldlen; 1142100384Speter 1143100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1144100384Speter return (EINVAL); 1145136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1146100384Speter if (error) 1147100384Speter return (error); 1148100384Speter mtx_lock(&Giant); 1149100384Speter if (uap->oldlenp) 1150100384Speter oldlen = fuword32(uap->oldlenp); 1151100384Speter else 1152100384Speter oldlen = 0; 1153100384Speter error = userland_sysctl(td, name, uap->namelen, 1154100384Speter uap->old, &oldlen, 1, 1155136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1156100384Speter if (error && error != ENOMEM) 1157100384Speter goto done2; 1158136404Speter if (uap->oldlenp) 1159100384Speter suword32(uap->oldlenp, j); 1160100384Speterdone2: 1161100384Speter mtx_unlock(&Giant); 1162100384Speter return (error); 1163100384Speter} 1164100384Speter 1165100384Speterstruct sigaction32 { 1166100384Speter u_int32_t sa_u; 1167100384Speter int sa_flags; 1168100384Speter sigset_t sa_mask; 1169100384Speter}; 1170100384Speter 1171121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1172121719Speter 1173100384Speterint 1174119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1175100384Speter{ 1176113859Sjhb struct sigaction32 s32; 1177113859Sjhb struct sigaction sa, osa, *sap; 1178100384Speter int error; 1179100384Speter 1180113859Sjhb if (uap->act) { 1181113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1182100384Speter if (error) 1183100384Speter return (error); 1184113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1185113859Sjhb CP(s32, sa, sa_flags); 1186113859Sjhb CP(s32, sa, sa_mask); 1187113859Sjhb sap = &sa; 1188113859Sjhb } else 1189113859Sjhb sap = NULL; 1190113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1191113859Sjhb if (error != 0 && uap->oact != NULL) { 1192113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1193113859Sjhb CP(osa, s32, sa_flags); 1194113859Sjhb CP(osa, s32, sa_mask); 1195113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1196100384Speter } 1197100384Speter return (error); 1198100384Speter} 1199100384Speter 1200114987Speter#ifdef COMPAT_FREEBSD4 1201114987Speterint 1202119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1203119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1204114987Speter{ 1205114987Speter struct sigaction32 s32; 1206114987Speter struct sigaction sa, osa, *sap; 1207114987Speter int error; 1208114987Speter 1209114987Speter if (uap->act) { 1210114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1211114987Speter if (error) 1212114987Speter return (error); 1213114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1214114987Speter CP(s32, sa, sa_flags); 1215114987Speter CP(s32, sa, sa_mask); 1216114987Speter sap = &sa; 1217114987Speter } else 1218114987Speter sap = NULL; 1219114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1220114987Speter if (error != 0 && uap->oact != NULL) { 1221114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1222114987Speter CP(osa, s32, sa_flags); 1223114987Speter CP(osa, s32, sa_mask); 1224114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1225114987Speter } 1226114987Speter return (error); 1227114987Speter} 1228114987Speter#endif 1229114987Speter 1230140481Spsint 1231140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1232140481Sps{ 1233140481Sps struct timespec32 rmt32, rqt32; 1234140481Sps struct timespec rmt, rqt; 1235140481Sps int error; 1236140481Sps 1237140481Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); 1238140481Sps if (error) 1239140481Sps return (error); 1240140481Sps 1241140481Sps CP(rqt32, rqt, tv_sec); 1242140481Sps CP(rqt32, rqt, tv_nsec); 1243140481Sps 1244140481Sps if (uap->rmtp && 1245140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1246140481Sps return (EFAULT); 1247140481Sps error = kern_nanosleep(td, &rqt, &rmt); 1248140481Sps if (error && uap->rmtp) { 1249140481Sps int error2; 1250140481Sps 1251140481Sps CP(rmt, rmt32, tv_sec); 1252140481Sps CP(rmt, rmt32, tv_nsec); 1253140481Sps 1254140481Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); 1255140481Sps if (error2) 1256140481Sps error = error2; 1257140481Sps } 1258140481Sps return (error); 1259140481Sps} 1260140481Sps 1261100384Speter#if 0 1262100384Speter 1263100384Speterint 1264119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1265100384Speter{ 1266100384Speter int error; 1267100384Speter caddr_t sg; 1268100384Speter struct yyy32 *p32, s32; 1269100384Speter struct yyy *p = NULL, s; 1270100384Speter 1271107849Salfred p32 = uap->zzz; 1272100384Speter if (p32) { 1273100384Speter sg = stackgap_init(); 1274100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1275107849Salfred uap->zzz = (struct yyy32 *)p; 1276100384Speter error = copyin(p32, &s32, sizeof(s32)); 1277100384Speter if (error) 1278100384Speter return (error); 1279100384Speter /* translate in */ 1280100384Speter error = copyout(&s, p, sizeof(s)); 1281100384Speter if (error) 1282100384Speter return (error); 1283100384Speter } 1284100384Speter error = xxx(td, (struct xxx_args *) uap); 1285100384Speter if (error) 1286100384Speter return (error); 1287100384Speter if (p32) { 1288100384Speter error = copyin(p, &s, sizeof(s)); 1289100384Speter if (error) 1290100384Speter return (error); 1291100384Speter /* translate out */ 1292100384Speter error = copyout(&s32, p32, sizeof(s32)); 1293100384Speter } 1294100384Speter return (error); 1295100384Speter} 1296100384Speter 1297100384Speter#endif 1298